root/arch/i386/i386/machdep.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cyrix_read_reg
  2. cyrix_write_reg
  3. cpuid
  4. cpu_startup
  5. i386_proc0_tss_ldt_init
  6. i386_init_pcb_tss_ldt
  7. allocsys
  8. setup_buffers
  9. winchip_cpu_setup
  10. cyrix3_setperf_setup
  11. cyrix3_cpu_setup
  12. cyrix6x86_cpu_setup
  13. natsem6x86_cpu_setup
  14. intel586_cpu_setup
  15. amd_family5_setperf_setup
  16. amd_family5_setup
  17. amd_family6_setperf_setup
  18. amd_family6_setup
  19. intelcore_update_sensor
  20. intel686_cpusensors_setup
  21. intel686_setperf_setup
  22. intel686_common_cpu_setup
  23. intel686_cpu_setup
  24. intel686_p4_cpu_setup
  25. tm86_cpu_setup
  26. intel686_cpu_name
  27. cyrix3_cpu_name
  28. identifycpu
  29. tm86_cpu_name
  30. cyrix3_get_bus_clock
  31. p4_get_bus_clock
  32. p3_get_bus_clock
  33. p4_update_cpuspeed
  34. p3_update_cpuspeed
  35. pentium_cpuspeed
  36. ibcs2_sendsig
  37. aston
  38. sendsig
  39. sys_sigreturn
  40. boot
  41. dumpconf
  42. cpu_dump
  43. reserve_dumppages
  44. dumpsys
  45. setregs
  46. setgate
  47. unsetgate
  48. setregion
  49. setsegment
  50. fix_f00f
  51. cpu_init_idt
  52. cpu_default_ldt
  53. cpu_alloc_ldt
  54. cpu_init_ldt
  55. init386
  56. cpu_exec_aout_makecmds
  57. consinit
  58. kgdb_port_init
  59. cpu_reset
  60. cpu_initclocks
  61. need_resched
  62. idt_vec_alloc
  63. idt_vec_set
  64. idt_vec_free
  65. cpu_sysctl
  66. bus_space_map
  67. _bus_space_map
  68. bus_space_alloc
  69. bus_mem_add_mapping
  70. bus_space_unmap
  71. _bus_space_unmap
  72. bus_space_free
  73. bus_space_subregion
  74. _bus_dmamap_create
  75. _bus_dmamap_destroy
  76. _bus_dmamap_load
  77. _bus_dmamap_load_mbuf
  78. _bus_dmamap_load_uio
  79. _bus_dmamap_load_raw
  80. _bus_dmamap_unload
  81. _bus_dmamem_alloc
  82. _bus_dmamem_free
  83. _bus_dmamem_map
  84. _bus_dmamem_unmap
  85. _bus_dmamem_mmap
  86. _bus_dmamap_load_buffer
  87. _bus_dmamem_alloc_range
  88. splassert_check
  89. i386_intlock
  90. i386_intunlock
  91. i386_softintlock
  92. i386_softintunlock
  93. softintr
  94. splraise
  95. splx
  96. spllower

    1 /*      $OpenBSD: machdep.c,v 1.403 2007/07/20 17:04:14 mk Exp $        */
    2 /*      $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $    */
    3 
    4 /*-
    5  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
   10  * NASA Ames Research Center.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgement:
   22  *      This product includes software developed by the NetBSD
   23  *      Foundation, Inc. and its contributors.
   24  * 4. Neither the name of The NetBSD Foundation nor the names of its
   25  *    contributors may be used to endorse or promote products derived
   26  *    from this software without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38  * POSSIBILITY OF SUCH DAMAGE.
   39  */
   40 
   41 /*-
   42  * Copyright (c) 1993, 1994, 1995, 1996 Charles M. Hannum.  All rights reserved.
   43  * Copyright (c) 1992 Terrence R. Lambert.
   44  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
   45  * All rights reserved.
   46  *
   47  * This code is derived from software contributed to Berkeley by
   48  * William Jolitz.
   49  *
   50  * Redistribution and use in source and binary forms, with or without
   51  * modification, are permitted provided that the following conditions
   52  * are met:
   53  * 1. Redistributions of source code must retain the above copyright
   54  *    notice, this list of conditions and the following disclaimer.
   55  * 2. Redistributions in binary form must reproduce the above copyright
   56  *    notice, this list of conditions and the following disclaimer in the
   57  *    documentation and/or other materials provided with the distribution.
   58  * 3. Neither the name of the University nor the names of its contributors
   59  *    may be used to endorse or promote products derived from this software
   60  *    without specific prior written permission.
   61  *
   62  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   63  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   64  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   65  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   66  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   67  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   68  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   69  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   70  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   71  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   72  * SUCH DAMAGE.
   73  *
   74  *      @(#)machdep.c   7.4 (Berkeley) 6/3/91
   75  */
   76 
   77 #include <sys/param.h>
   78 #include <sys/systm.h>
   79 #include <sys/signalvar.h>
   80 #include <sys/kernel.h>
   81 #include <sys/proc.h>
   82 #include <sys/user.h>
   83 #include <sys/exec.h>
   84 #include <sys/buf.h>
   85 #include <sys/reboot.h>
   86 #include <sys/conf.h>
   87 #include <sys/file.h>
   88 #include <sys/timeout.h>
   89 #include <sys/malloc.h>
   90 #include <sys/mbuf.h>
   91 #include <sys/msgbuf.h>
   92 #include <sys/mount.h>
   93 #include <sys/vnode.h>
   94 #include <sys/device.h>
   95 #include <sys/extent.h>
   96 #include <sys/sysctl.h>
   97 #include <sys/syscallargs.h>
   98 #include <sys/core.h>
   99 #include <sys/kcore.h>
  100 #include <sys/sensors.h>
  101 #ifdef SYSVMSG
  102 #include <sys/msg.h>
  103 #endif
  104 
  105 #ifdef KGDB
  106 #include <sys/kgdb.h>
  107 #endif
  108 
  109 #include <dev/cons.h>
  110 #include <stand/boot/bootarg.h>
  111 
  112 #include <uvm/uvm_extern.h>
  113 
  114 #define _I386_BUS_DMA_PRIVATE
  115 #include <machine/bus.h>
  116 
  117 #include <machine/cpu.h>
  118 #include <machine/cpufunc.h>
  119 #include <machine/cpuvar.h>
  120 #include <machine/gdt.h>
  121 #include <machine/pio.h>
  122 #include <machine/bus.h>
  123 #include <machine/psl.h>
  124 #include <machine/reg.h>
  125 #include <machine/specialreg.h>
  126 #include <machine/biosvar.h>
  127 
  128 #include <dev/rndvar.h>
  129 #include <dev/isa/isareg.h>
  130 #include <dev/isa/isavar.h>
  131 #include <dev/ic/i8042reg.h>
  132 #include <dev/ic/mc146818reg.h>
  133 #include <i386/isa/isa_machdep.h>
  134 #include <i386/isa/nvram.h>
  135 
  136 #include "acpi.h"
  137 #if NACPI > 0
  138 #include <dev/acpi/acpivar.h>
  139 #endif
  140 
  141 #include "apm.h"
  142 #if NAPM > 0
  143 #include <machine/apmvar.h>
  144 #endif
  145 
  146 #ifdef DDB
  147 #include <machine/db_machdep.h>
  148 #include <ddb/db_access.h>
  149 #include <ddb/db_sym.h>
  150 #include <ddb/db_extern.h>
  151 #endif
  152 
  153 #ifdef VM86
  154 #include <machine/vm86.h>
  155 #endif
  156 
  157 #include "isa.h"
  158 #include "isadma.h"
  159 #include "npx.h"
  160 #if NNPX > 0
  161 extern struct proc *npxproc;
  162 #endif
  163 
  164 #include "bios.h"
  165 #include "com.h"
  166 #include "pccom.h"
  167 
  168 #if NPCCOM > 0
  169 #include <sys/termios.h>
  170 #include <dev/ic/comreg.h>
  171 #if NCOM > 0
  172 #include <dev/ic/comvar.h>
  173 #elif NPCCOM > 0
  174 #include <arch/i386/isa/pccomvar.h>
  175 #endif
  176 #endif /* NCOM > 0 || NPCCOM > 0 */
  177 
  178 /* the following is used externally (sysctl_hw) */
  179 char machine[] = MACHINE;
  180 
  181 /*
  182  * Declare these as initialized data so we can patch them.
  183  */
  184 #if NAPM > 0
  185 int     cpu_apmhalt = 0;        /* sysctl'd to 1 for halt -p hack */
  186 #endif
  187 
  188 #ifdef USER_LDT
  189 int     user_ldt_enable = 0;    /* sysctl'd to 1 to enable */
  190 #endif
  191 
  192 #ifndef BUFCACHEPERCENT
  193 #define BUFCACHEPERCENT 10
  194 #endif
  195 
  196 #ifdef  BUFPAGES
  197 int     bufpages = BUFPAGES;
  198 #else
  199 int     bufpages = 0;
  200 #endif
  201 int     bufcachepercent = BUFCACHEPERCENT;
  202 
  203 extern int      boothowto;
  204 int     physmem;
  205 
  206 struct dumpmem {
  207         paddr_t start;
  208         paddr_t end;
  209 } dumpmem[VM_PHYSSEG_MAX];
  210 u_int ndumpmem;
  211 
  212 /*
  213  * These variables are needed by /sbin/savecore
  214  */
  215 u_long  dumpmag = 0x8fca0101;   /* magic number */
  216 int     dumpsize = 0;           /* pages */
  217 long    dumplo = 0;             /* blocks */
  218 
  219 int     cpu_class;
  220 int     i386_fpu_present;
  221 int     i386_fpu_exception;
  222 int     i386_fpu_fdivbug;
  223 
  224 int     i386_use_fxsave;
  225 int     i386_has_sse;
  226 int     i386_has_sse2;
  227 int     i386_has_xcrypt;
  228 
  229 bootarg_t *bootargp;
  230 paddr_t avail_end;
  231 
  232 struct vm_map *exec_map = NULL;
  233 struct vm_map *phys_map = NULL;
  234 
  235 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
  236 int p4_model;
  237 int p3_early;
  238 void (*update_cpuspeed)(void) = NULL;
  239 #endif
  240 int kbd_reset;
  241 
  242 #if !defined(SMALL_KERNEL)
  243 int bus_clock;
  244 #endif
  245 void (*setperf_setup)(struct cpu_info *);
  246 int setperf_prio = 0;           /* for concurrent handlers */
  247 
  248 void (*cpusensors_setup)(struct cpu_info *);
  249 
  250 void (*delay_func)(int) = i8254_delay;
  251 void (*initclock_func)(void) = i8254_initclocks;
  252 
  253 /*
  254  * Extent maps to manage I/O and ISA memory hole space.  Allocate
  255  * storage for 8 regions in each, initially.  Later, ioport_malloc_safe
  256  * will indicate that it's safe to use malloc() to dynamically allocate
  257  * region descriptors.
  258  *
  259  * N.B. At least two regions are _always_ allocated from the iomem
  260  * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM).
  261  *
  262  * The extent maps are not static!  Machine-dependent ISA and EISA
  263  * routines need access to them for bus address space allocation.
  264  */
  265 static  long ioport_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)];
  266 static  long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)];
  267 struct  extent *ioport_ex;
  268 struct  extent *iomem_ex;
  269 static  int ioport_malloc_safe;
  270 
  271 caddr_t allocsys(caddr_t);
  272 void    setup_buffers(void);
  273 void    dumpsys(void);
  274 int     cpu_dump(void);
  275 void    init386(paddr_t);
  276 void    consinit(void);
  277 void    (*cpuresetfn)(void);
  278 
  279 int     bus_mem_add_mapping(bus_addr_t, bus_size_t,
  280             int, bus_space_handle_t *);
  281 int     _bus_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *,
  282     bus_size_t, struct proc *, int, paddr_t *, int *, int);
  283 
  284 #ifdef KGDB
  285 #ifndef KGDB_DEVNAME
  286 #ifdef __i386__
  287 #define KGDB_DEVNAME "pccom"
  288 #else
  289 #define KGDB_DEVNAME "com"
  290 #endif
  291 #endif /* KGDB_DEVNAME */
  292 char kgdb_devname[] = KGDB_DEVNAME;
  293 #if (NCOM > 0 || NPCCOM > 0)
  294 #ifndef KGDBADDR
  295 #define KGDBADDR 0x3f8
  296 #endif
  297 int comkgdbaddr = KGDBADDR;
  298 #ifndef KGDBRATE
  299 #define KGDBRATE TTYDEF_SPEED
  300 #endif
  301 int comkgdbrate = KGDBRATE;
  302 #ifndef KGDBMODE
  303 #define KGDBMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
  304 #endif
  305 int comkgdbmode = KGDBMODE;
  306 #endif /* NCOM  || NPCCOM */
  307 void kgdb_port_init(void);
  308 #endif /* KGDB */
  309 
  310 #ifdef APERTURE
  311 #ifdef INSECURE
  312 int allowaperture = 1;
  313 #else
  314 int allowaperture = 0;
  315 #endif
  316 #endif
  317 
  318 void    winchip_cpu_setup(struct cpu_info *);
  319 void    amd_family5_setperf_setup(struct cpu_info *);
  320 void    amd_family5_setup(struct cpu_info *);
  321 void    amd_family6_setperf_setup(struct cpu_info *);
  322 void    amd_family6_setup(struct cpu_info *);
  323 void    cyrix3_setperf_setup(struct cpu_info *);
  324 void    cyrix3_cpu_setup(struct cpu_info *);
  325 void    cyrix6x86_cpu_setup(struct cpu_info *);
  326 void    natsem6x86_cpu_setup(struct cpu_info *);
  327 void    intel586_cpu_setup(struct cpu_info *);
  328 void    intel686_cpusensors_setup(struct cpu_info *);
  329 void    intel686_setperf_setup(struct cpu_info *);
  330 void    intel686_common_cpu_setup(struct cpu_info *);
  331 void    intel686_cpu_setup(struct cpu_info *);
  332 void    intel686_p4_cpu_setup(struct cpu_info *);
  333 void    intelcore_update_sensor(void *);
  334 void    tm86_cpu_setup(struct cpu_info *);
  335 char *  intel686_cpu_name(int);
  336 char *  cyrix3_cpu_name(int, int);
  337 char *  tm86_cpu_name(int);
  338 void    cyrix3_get_bus_clock(struct cpu_info *);
  339 void    p4_get_bus_clock(struct cpu_info *);
  340 void    p3_get_bus_clock(struct cpu_info *);
  341 void    p4_update_cpuspeed(void);
  342 void    p3_update_cpuspeed(void);
  343 int     pentium_cpuspeed(int *);
  344 
  345 static __inline u_char
  346 cyrix_read_reg(u_char reg)
  347 {
  348         outb(0x22, reg);
  349         return inb(0x23);
  350 }
  351 
  352 static __inline void
  353 cyrix_write_reg(u_char reg, u_char data)
  354 {
  355         outb(0x22, reg);
  356         outb(0x23, data);
  357 }
  358 
  359 /*
  360  * cpuid instruction.  request in eax, result in eax, ebx, ecx, edx.
  361  * requires caller to provide u_int32_t regs[4] array.
  362  */
  363 void
  364 cpuid(u_int32_t ax, u_int32_t *regs)
  365 {
  366         __asm __volatile(
  367             "cpuid\n\t"
  368             "movl       %%eax, 0(%2)\n\t"
  369             "movl       %%ebx, 4(%2)\n\t"
  370             "movl       %%ecx, 8(%2)\n\t"
  371             "movl       %%edx, 12(%2)\n\t"
  372             :"=a" (ax)
  373             :"0" (ax), "S" (regs)
  374             :"bx", "cx", "dx");
  375 }
  376 
  377 /*
  378  * Machine-dependent startup code
  379  */
  380 void
  381 cpu_startup()
  382 {
  383         unsigned i;
  384         caddr_t v;
  385         int sz;
  386         vaddr_t minaddr, maxaddr, va;
  387         paddr_t pa;
  388 
  389         /*
  390          * Initialize error message buffer (at end of core).
  391          * (space reserved in pmap_bootstrap)
  392          */
  393         pa = avail_end;
  394         va = (vaddr_t)msgbufp;
  395         for (i = 0; i < btoc(MSGBUFSIZE); i++) {
  396                 pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE);
  397                 va += PAGE_SIZE;
  398                 pa += PAGE_SIZE;
  399         }
  400         pmap_update(pmap_kernel());
  401         initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE));
  402 
  403         printf("%s", version);
  404         startrtclock();
  405 
  406         /*
  407          * We need to call identifycpu here early, so users have at least some
  408          * basic information, if booting hangs later on.
  409          */
  410         strlcpy(curcpu()->ci_dev.dv_xname, "cpu0",
  411             sizeof(curcpu()->ci_dev.dv_xname));
  412         curcpu()->ci_signature = cpu_id;
  413         curcpu()->ci_feature_flags = cpu_feature;
  414         identifycpu(curcpu());
  415 
  416         printf("real mem  = %llu (%lluMB)\n", ctob((unsigned long long)physmem),
  417             ctob((unsigned long long)physmem)/1024U/1024U);
  418 
  419         /*
  420          * Find out how much space we need, allocate it,
  421          * and then give everything true virtual addresses.
  422          */
  423         sz = (int)allocsys((caddr_t)0);
  424         if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0)
  425                 panic("startup: no room for tables");
  426         if (allocsys(v) - v != sz)
  427                 panic("startup: table size inconsistency");
  428 
  429         /*
  430          * Now allocate buffers proper.  They are different than the above
  431          * in that they usually occupy more virtual memory than physical.
  432          */
  433         setup_buffers();
  434 
  435         /*
  436          * Allocate a submap for exec arguments.  This map effectively
  437          * limits the number of processes exec'ing at any time.
  438          */
  439         minaddr = vm_map_min(kernel_map);
  440         exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
  441                                    16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
  442 
  443         /*
  444          * Allocate a submap for physio
  445          */
  446         phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
  447                                    VM_PHYS_SIZE, 0, FALSE, NULL);
  448 
  449         printf("avail mem = %llu (%lluMB)\n",
  450             ptoa((unsigned long long)uvmexp.free),
  451             ptoa((unsigned long long)uvmexp.free)/1024U/1024U);
  452 
  453         /*
  454          * Set up buffers, so they can be used to read disk labels.
  455          */
  456         bufinit();
  457 
  458         /*
  459          * Configure the system.
  460          */
  461         if (boothowto & RB_CONFIG) {
  462 #ifdef BOOT_CONFIG
  463                 user_config();
  464 #else
  465                 printf("kernel does not support -c; continuing..\n");
  466 #endif
  467         }
  468         ioport_malloc_safe = 1;
  469 }
  470 
  471 /*
  472  * Set up proc0's TSS and LDT.
  473  */
  474 void
  475 i386_proc0_tss_ldt_init()
  476 {
  477         int x;
  478         struct pcb *pcb;
  479 
  480         curpcb = pcb = &proc0.p_addr->u_pcb;
  481 
  482         pcb->pcb_tss.tss_ioopt =
  483             ((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss) << 16;
  484         for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++)
  485                 pcb->pcb_iomap[x] = 0xffffffff;
  486         pcb->pcb_iomap_pad = 0xff;
  487 
  488         pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL);
  489         pcb->pcb_ldt = ldt;
  490         pcb->pcb_cr0 = rcr0();
  491         pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
  492         pcb->pcb_tss.tss_esp0 = (int)proc0.p_addr + USPACE - 16;
  493         proc0.p_md.md_regs = (struct trapframe *)pcb->pcb_tss.tss_esp0 - 1;
  494         proc0.p_md.md_tss_sel = tss_alloc(pcb);
  495 
  496         ltr(proc0.p_md.md_tss_sel);
  497         lldt(pcb->pcb_ldt_sel);
  498 }
  499 
  500 #ifdef MULTIPROCESSOR
  501 void
  502 i386_init_pcb_tss_ldt(struct cpu_info *ci)
  503 {
  504         int x;
  505         struct pcb *pcb = ci->ci_idle_pcb;
  506 
  507         pcb->pcb_tss.tss_ioopt =
  508             ((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss) << 16;
  509         for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++)
  510                 pcb->pcb_iomap[x] = 0xffffffff;
  511         pcb->pcb_iomap_pad = 0xff;
  512 
  513         pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL);
  514         pcb->pcb_ldt = ci->ci_ldt;
  515         pcb->pcb_cr0 = rcr0();
  516         ci->ci_idle_tss_sel = tss_alloc(pcb);
  517 }
  518 #endif  /* MULTIPROCESSOR */
  519 
  520 
  521 /*
  522  * Allocate space for system data structures.  We are given
  523  * a starting virtual address and we return a final virtual
  524  * address; along the way we set each data structure pointer.
  525  *
  526  * We call allocsys() with 0 to find out how much space we want,
  527  * allocate that much and fill it with zeroes, and then call
  528  * allocsys() again with the correct base virtual address.
  529  */
  530 caddr_t
  531 allocsys(caddr_t v)
  532 {
  533 
  534 #define valloc(name, type, num) \
  535             v = (caddr_t)(((name) = (type *)v) + (num))
  536 
  537 #ifdef SYSVMSG
  538         valloc(msgpool, char, msginfo.msgmax);
  539         valloc(msgmaps, struct msgmap, msginfo.msgseg);
  540         valloc(msghdrs, struct msg, msginfo.msgtql);
  541         valloc(msqids, struct msqid_ds, msginfo.msgmni);
  542 #endif
  543 
  544         return v;
  545 }
  546 
  547 void
  548 setup_buffers()
  549 {
  550         /*
  551          * Determine how many buffers to allocate.  We use bufcachepercent%
  552          * of the memory below 4GB.
  553          */
  554         if (bufpages == 0)
  555                 bufpages = btoc(avail_end) * bufcachepercent / 100;
  556 
  557         /* Restrict to at most 25% filled kvm */
  558         if (bufpages >
  559             (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
  560                 bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
  561                     PAGE_SIZE / 4;
  562 }
  563 
  564 /*
  565  * Info for CTL_HW
  566  */
  567 char    cpu_model[120];
  568 
  569 /*
  570  * Note: these are just the ones that may not have a cpuid instruction.
  571  * We deal with the rest in a different way.
  572  */
  573 const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[] = {
  574         { CPUVENDOR_INTEL, "Intel", "386SX",    CPUCLASS_386,
  575                 NULL},                          /* CPU_386SX */
  576         { CPUVENDOR_INTEL, "Intel", "386DX",    CPUCLASS_386,
  577                 NULL},                          /* CPU_386   */
  578         { CPUVENDOR_INTEL, "Intel", "486SX",    CPUCLASS_486,
  579                 NULL},                          /* CPU_486SX */
  580         { CPUVENDOR_INTEL, "Intel", "486DX",    CPUCLASS_486,
  581                 NULL},                          /* CPU_486   */
  582         { CPUVENDOR_CYRIX, "Cyrix", "486DLC",   CPUCLASS_486,
  583                 NULL},                          /* CPU_486DLC */
  584         { CPUVENDOR_CYRIX, "Cyrix", "6x86",     CPUCLASS_486,
  585                 cyrix6x86_cpu_setup},           /* CPU_6x86 */
  586         { CPUVENDOR_NEXGEN,"NexGen","586",      CPUCLASS_386,
  587                 NULL},                          /* CPU_NX586 */
  588 };
  589 
  590 const char *classnames[] = {
  591         "386",
  592         "486",
  593         "586",
  594         "686"
  595 };
  596 
  597 const char *modifiers[] = {
  598         "",
  599         "OverDrive ",
  600         "Dual ",
  601         ""
  602 };
  603 
  604 const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = {
  605         {
  606                 "GenuineIntel",
  607                 CPUVENDOR_INTEL,
  608                 "Intel",
  609                 /* Family 4 */
  610                 { {
  611                         CPUCLASS_486,
  612                         {
  613                                 "486DX", "486DX", "486SX", "486DX2", "486SL",
  614                                 "486SX2", 0, "486DX2 W/B",
  615                                 "486DX4", 0, 0, 0, 0, 0, 0, 0,
  616                                 "486"           /* Default */
  617                         },
  618                         NULL
  619                 },
  620                 /* Family 5 */
  621                 {
  622                         CPUCLASS_586,
  623                         {
  624                                 "Pentium (A-step)", "Pentium (P5)",
  625                                 "Pentium (P54C)", "Pentium (P24T)",
  626                                 "Pentium/MMX", "Pentium", 0,
  627                                 "Pentium (P54C)", "Pentium/MMX",
  628                                 0, 0, 0, 0, 0, 0, 0,
  629                                 "Pentium"       /* Default */
  630                         },
  631                         intel586_cpu_setup
  632                 },
  633                 /* Family 6 */
  634                 {
  635                         CPUCLASS_686,
  636                         {
  637                                 "Pentium Pro", "Pentium Pro", 0,
  638                                 "Pentium II", "Pentium Pro",
  639                                 "Pentium II/Celeron",
  640                                 "Celeron",
  641                                 "Pentium III",
  642                                 "Pentium III",
  643                                 "Pentium M",
  644                                 "Pentium III Xeon",
  645                                 "Pentium III", 0,
  646                                 "Pentium M",
  647                                 "Core Duo/Solo", 0,
  648                                 "Pentium Pro, II or III"        /* Default */
  649                         },
  650                         intel686_cpu_setup
  651                 },
  652                 /* Family 7 */
  653                 {
  654                         CPUCLASS_686,
  655                 } ,
  656                 /* Family 8 */
  657                 {
  658                         CPUCLASS_686,
  659                 } ,
  660                 /* Family 9 */
  661                 {
  662                         CPUCLASS_686,
  663                 } ,
  664                 /* Family A */
  665                 {
  666                         CPUCLASS_686,
  667                 } ,
  668                 /* Family B */
  669                 {
  670                         CPUCLASS_686,
  671                 } ,
  672                 /* Family C */
  673                 {
  674                         CPUCLASS_686,
  675                 } ,
  676                 /* Family D */
  677                 {
  678                         CPUCLASS_686,
  679                 } ,
  680                 /* Family E */
  681                 {
  682                         CPUCLASS_686,
  683                 } ,
  684                 /* Family F */
  685                 {
  686                         CPUCLASS_686,
  687                         {
  688                                 "Pentium 4", 0, 0, 0,
  689                                 0, 0, 0, 0,
  690                                 0, 0, 0, 0,
  691                                 0, 0, 0, 0,
  692                                 "Pentium 4"     /* Default */
  693                         },
  694                         intel686_p4_cpu_setup
  695                 } }
  696         },
  697         {
  698                 "AuthenticAMD",
  699                 CPUVENDOR_AMD,
  700                 "AMD",
  701                 /* Family 4 */
  702                 { {
  703                         CPUCLASS_486,
  704                         {
  705                                 0, 0, 0, "Am486DX2 W/T",
  706                                 0, 0, 0, "Am486DX2 W/B",
  707                                 "Am486DX4 W/T or Am5x86 W/T 150",
  708                                 "Am486DX4 W/B or Am5x86 W/B 150", 0, 0,
  709                                 0, 0, "Am5x86 W/T 133/160",
  710                                 "Am5x86 W/B 133/160",
  711                                 "Am486 or Am5x86"       /* Default */
  712                         },
  713                         NULL
  714                 },
  715                 /* Family 5 */
  716                 {
  717                         CPUCLASS_586,
  718                         {
  719                                 "K5", "K5", "K5", "K5", 0, 0, "K6",
  720                                 "K6", "K6-2", "K6-III", 0, 0, 0,
  721                                 "K6-2+/III+", 0, 0,
  722                                 "K5 or K6"              /* Default */
  723                         },
  724                         amd_family5_setup
  725                 },
  726                 /* Family 6 */
  727                 {
  728                         CPUCLASS_686,
  729                         {
  730                                 0, "Athlon Model 1", "Athlon Model 2",
  731                                 "Duron Model 3",
  732                                 "Athlon Model 4",
  733                                 0, "Athlon XP Model 6",
  734                                 "Duron Model 7",
  735                                 "Athlon XP Model 8",
  736                                 0, "Athlon XP Model 10",
  737                                 0, 0, 0, 0, 0,
  738                                 "K7"            /* Default */
  739                         },
  740                         amd_family6_setup
  741                 },
  742                 /* Family 7 */
  743                 {
  744                         CPUCLASS_686,
  745                 } ,
  746                 /* Family 8 */
  747                 {
  748                         CPUCLASS_686,
  749                 } ,
  750                 /* Family 9 */
  751                 {
  752                         CPUCLASS_686,
  753                 } ,
  754                 /* Family A */
  755                 {
  756                         CPUCLASS_686,
  757                 } ,
  758                 /* Family B */
  759                 {
  760                         CPUCLASS_686,
  761                 } ,
  762                 /* Family C */
  763                 {
  764                         CPUCLASS_686,
  765                 } ,
  766                 /* Family D */
  767                 {
  768                         CPUCLASS_686,
  769                 } ,
  770                 /* Family E */
  771                 {
  772                         CPUCLASS_686,
  773                 } ,
  774                 /* Family F */
  775                 {
  776                         CPUCLASS_686,
  777                         {
  778                                 0, 0, 0, 0, "Athlon64",
  779                                 "Opteron or Athlon64FX", 0, 0,
  780                                 0, 0, 0, 0, 0, 0, 0, 0,
  781                                 "AMD64"                 /* DEFAULT */
  782                         },
  783                         amd_family6_setup
  784                 } }
  785         },
  786         {
  787                 "CyrixInstead",
  788                 CPUVENDOR_CYRIX,
  789                 "Cyrix",
  790                 /* Family 4 */
  791                 { {
  792                         CPUCLASS_486,
  793                         {
  794                                 0, 0, 0, "MediaGX", 0, 0, 0, 0, "5x86", 0, 0,
  795                                 0, 0, 0, 0,
  796                                 "486 class"     /* Default */
  797                         },
  798                         NULL
  799                 },
  800                 /* Family 5 */
  801                 {
  802                         CPUCLASS_586,
  803                         {
  804                                 0, 0, "6x86", 0, "GXm", 0, 0, 0, 0, 0,
  805                                 0, 0, 0, 0, 0, 0,
  806                                 "586 class"     /* Default */
  807                         },
  808                         cyrix6x86_cpu_setup
  809                 },
  810                 /* Family 6 */
  811                 {
  812                         CPUCLASS_686,
  813                         {
  814                                 "6x86MX", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  815                                 0, 0, 0, 0,
  816                                 "686 class"     /* Default */
  817                         },
  818                         NULL
  819                 } }
  820         },
  821         {
  822                 "CentaurHauls",
  823                 CPUVENDOR_IDT,
  824                 "IDT",
  825                 /* Family 4, not available from IDT */
  826                 { {
  827                         CPUCLASS_486,
  828                         {
  829                                 0, 0, 0, 0, 0, 0, 0, 0,
  830                                 0, 0, 0, 0, 0, 0, 0, 0,
  831                                 "486 class"             /* Default */
  832                         },
  833                         NULL
  834                 },
  835                 /* Family 5 */
  836                 {
  837                         CPUCLASS_586,
  838                         {
  839                                 0, 0, 0, 0, "WinChip C6", 0, 0, 0,
  840                                 "WinChip 2", "WinChip 3", 0, 0, 0, 0, 0, 0,
  841                                 "WinChip"               /* Default */
  842                         },
  843                         winchip_cpu_setup
  844                 },
  845                 /* Family 6 */
  846                 {
  847                         CPUCLASS_686,
  848                         {
  849                                 0, 0, 0, 0, 0, 0,
  850                                 "C3 Samuel",
  851                                 "C3 Samuel 2/Ezra",
  852                                 "C3 Ezra-T",
  853                                 "C3 Nehemiah", "C3 Esther", 0, 0, 0, 0, 0,
  854                                 "C3"            /* Default */
  855                         },
  856                         cyrix3_cpu_setup
  857                 } }
  858         },
  859         {
  860                 "RiseRiseRise",
  861                 CPUVENDOR_RISE,
  862                 "Rise",
  863                 /* Family 4, not available from Rise */
  864                 { {
  865                         CPUCLASS_486,
  866                         {
  867                                 0, 0, 0, 0, 0, 0, 0, 0,
  868                                 0, 0, 0, 0, 0, 0, 0, 0,
  869                                 "486 class"             /* Default */
  870                         },
  871                         NULL
  872                 },
  873                 /* Family 5 */
  874                 {
  875                         CPUCLASS_586,
  876                         {
  877                                 "mP6", 0, "mP6", 0, 0, 0, 0, 0,
  878                                 0, 0, 0, 0, 0, 0, 0, 0,
  879                                 "mP6"                   /* Default */
  880                         },
  881                         NULL
  882                 },
  883                 /* Family 6, not yet available from Rise */
  884                 {
  885                         CPUCLASS_686,
  886                         {
  887                                 0, 0, 0, 0, 0, 0, 0, 0,
  888                                 0, 0, 0, 0, 0, 0, 0, 0,
  889                                 "686 class"             /* Default */
  890                         },
  891                         NULL
  892                 } }
  893         },
  894         {
  895                 "GenuineTMx86",
  896                 CPUVENDOR_TRANSMETA,
  897                 "Transmeta",
  898                 /* Family 4, not available from Transmeta */
  899                 { {
  900                         CPUCLASS_486,
  901                         {
  902                                 0, 0, 0, 0, 0, 0, 0, 0,
  903                                 0, 0, 0, 0, 0, 0, 0, 0,
  904                                 "486 class"             /* Default */
  905                         },
  906                         NULL
  907                 },
  908                 /* Family 5 */
  909                 {
  910                         CPUCLASS_586,
  911                         {
  912                                 0, 0, 0, 0, "TMS5x00", 0, 0,
  913                                 0, 0, 0, 0, 0, 0, 0, 0, 0,
  914                                 "TMS5x00"               /* Default */
  915                         },
  916                         tm86_cpu_setup
  917                 },
  918                 /* Family 6, not yet available from Transmeta */
  919                 {
  920                         CPUCLASS_686,
  921                         {
  922                                 0, 0, 0, 0, 0, 0, 0, 0,
  923                                 0, 0, 0, 0, 0, 0, 0, 0,
  924                                 "686 class"             /* Default */
  925                         },
  926                         NULL
  927                 } }
  928         },
  929         {
  930                 "Geode by NSC",
  931                 CPUVENDOR_NS,
  932                 "National Semiconductor",
  933                 /* Family 4, not available from National Semiconductor */
  934                 { {
  935                         CPUCLASS_486,
  936                         {
  937                                 0, 0, 0, 0, 0, 0, 0, 0,
  938                                 0, 0, 0, 0, 0, 0, 0, 0,
  939                                 "486 class"     /* Default */
  940                         },
  941                         NULL
  942                 },
  943                 /* Family 5 */
  944                 {
  945                         CPUCLASS_586,
  946                         {
  947                                 0, 0, 0, 0, "Geode GX1", 0, 0, 0, 0, 0,
  948                                 0, 0, 0, 0, 0, 0,
  949                                 "586 class"     /* Default */
  950                         },
  951                         natsem6x86_cpu_setup
  952                 } }
  953         },
  954         {
  955                 "SiS SiS SiS ",
  956                 CPUVENDOR_SIS,
  957                 "SiS",
  958                 /* Family 4, not available from SiS */
  959                 { {
  960                         CPUCLASS_486,
  961                         {
  962                                 0, 0, 0, 0, 0, 0, 0, 0,
  963                                 0, 0, 0, 0, 0, 0, 0, 0,
  964                                 "486 class"     /* Default */
  965                         },
  966                         NULL
  967                 },
  968                 /* Family 5 */
  969                 {
  970                         CPUCLASS_586,
  971                         {
  972                                 "SiS55x", 0, 0, 0, 0, 0, 0, 0, 0, 0,
  973                                 0, 0, 0, 0, 0, 0,
  974                                 "586 class"     /* Default */
  975                         },
  976                         NULL
  977                 } }
  978         }
  979 };
  980 
  981 const struct cpu_cpuid_feature i386_cpuid_features[] = {
  982         { CPUID_FPU,    "FPU" },
  983         { CPUID_VME,    "V86" },
  984         { CPUID_DE,     "DE" },
  985         { CPUID_PSE,    "PSE" },
  986         { CPUID_TSC,    "TSC" },
  987         { CPUID_MSR,    "MSR" },
  988         { CPUID_PAE,    "PAE" },
  989         { CPUID_MCE,    "MCE" },
  990         { CPUID_CX8,    "CX8" },
  991         { CPUID_APIC,   "APIC" },
  992         { CPUID_SYS1,   "SYS" },
  993         { CPUID_SEP,    "SEP" },
  994         { CPUID_MTRR,   "MTRR" },
  995         { CPUID_PGE,    "PGE" },
  996         { CPUID_MCA,    "MCA" },
  997         { CPUID_CMOV,   "CMOV" },
  998         { CPUID_PAT,    "PAT" },
  999         { CPUID_PSE36,  "PSE36" },
 1000         { CPUID_SER,    "SER" },
 1001         { CPUID_CFLUSH, "CFLUSH" },
 1002         { CPUID_DS,     "DS" },
 1003         { CPUID_ACPI,   "ACPI" },
 1004         { CPUID_MMX,    "MMX" },
 1005         { CPUID_FXSR,   "FXSR" },
 1006         { CPUID_SSE,    "SSE" },
 1007         { CPUID_SSE2,   "SSE2" },
 1008         { CPUID_SS,     "SS" },
 1009         { CPUID_HTT,    "HTT" },
 1010         { CPUID_TM,     "TM" },
 1011         { CPUID_SBF,    "SBF" },
 1012         { CPUID_3DNOW,  "3DNOW" },
 1013 };
 1014 
 1015 const struct cpu_cpuid_feature i386_cpuid_ecxfeatures[] = {
 1016         { CPUIDECX_SSE3,        "SSE3" },
 1017         { CPUIDECX_MWAIT,       "MWAIT" },
 1018         { CPUIDECX_DSCPL,       "DS-CPL" },
 1019         { CPUIDECX_VMX,         "VMX" },
 1020         { CPUIDECX_EST,         "EST" },
 1021         { CPUIDECX_TM2,         "TM2" },
 1022         { CPUIDECX_CNXTID,      "CNXT-ID" },
 1023         { CPUIDECX_CX16,        "CX16" },
 1024         { CPUIDECX_XTPR,        "xTPR" },
 1025 };
 1026 
 1027 void
 1028 winchip_cpu_setup(struct cpu_info *ci)
 1029 {
 1030 #if defined(I586_CPU)
 1031 
 1032         switch ((ci->ci_signature >> 4) & 15) { /* model */
 1033         case 4: /* WinChip C6 */
 1034                 ci->ci_feature_flags &= ~CPUID_TSC;
 1035                 /* Disable RDTSC instruction from user-level. */
 1036                 lcr4(rcr4() | CR4_TSD);
 1037                 printf("%s: TSC disabled\n", ci->ci_dev.dv_xname);
 1038                 break;
 1039         }
 1040 #endif
 1041 }
 1042 
 1043 #if defined(I686_CPU) && !defined(SMALL_KERNEL)
 1044 void
 1045 cyrix3_setperf_setup(struct cpu_info *ci)
 1046 {
 1047         if (cpu_ecxfeature & CPUIDECX_EST) {
 1048                 if (rdmsr(MSR_MISC_ENABLE) & (1 << 16))
 1049                         est_init(ci->ci_dev.dv_xname, CPUVENDOR_VIA);
 1050                 else
 1051                         printf("%s: Enhanced SpeedStep disabled by BIOS\n",
 1052                             ci->ci_dev.dv_xname);
 1053         }
 1054 }
 1055 #endif
 1056 
 1057 void
 1058 cyrix3_cpu_setup(struct cpu_info *ci)
 1059 {
 1060 #if defined(I686_CPU)
 1061         int model = (ci->ci_signature >> 4) & 15;
 1062         int step = ci->ci_signature & 15;
 1063 
 1064         u_int64_t msreg;
 1065         u_int32_t regs[4];
 1066         unsigned int val;
 1067 #if !defined(SMALL_KERNEL)
 1068         extern void (*pagezero)(void *, size_t);
 1069         extern void i686_pagezero(void *, size_t);
 1070 
 1071         pagezero = i686_pagezero;
 1072 
 1073         cyrix3_get_bus_clock(ci);
 1074 
 1075         setperf_setup = cyrix3_setperf_setup;
 1076 #endif
 1077 
 1078         switch (model) {
 1079         case 6: /* C3 Samuel 1 */
 1080         case 7: /* C3 Samuel 2 or C3 Ezra */
 1081         case 8: /* C3 Ezra-T */
 1082                 cpuid(0x80000001, regs);
 1083                 val = regs[3];
 1084                 if (val & (1U << 31)) {
 1085                         cpu_feature |= CPUID_3DNOW;
 1086                 } else {
 1087                         cpu_feature &= ~CPUID_3DNOW;
 1088                 }
 1089                 break;
 1090 
 1091         case 9:
 1092                 if (step < 3)
 1093                         break;
 1094                 /*
 1095                  * C3 Nehemiah: fall through.
 1096                  */
 1097         case 10:
 1098                 /*
 1099                  * C3 Nehemiah/Esther:
 1100                  * First we check for extended feature flags, and then
 1101                  * (if present) retrieve the ones at 0xC0000001.  In this
 1102                  * bit 2 tells us if the RNG is present.  Bit 3 tells us
 1103                  * if the RNG has been enabled.  In order to use the RNG
 1104                  * we need 3 things:  We need an RNG, we need the FXSR bit
 1105                  * enabled in cr4 (SSE/SSE2 stuff), and we need to have
 1106                  * Bit 6 of MSR 0x110B set to 1 (the default), which will
 1107                  * show up as bit 3 set here.
 1108                  */
 1109                 cpuid(0xC0000000, regs); /* Check for RNG */
 1110                 val = regs[0];
 1111                 if (val >= 0xC0000001) {
 1112                         cpuid(0xC0000001, regs);
 1113                         val = regs[3];
 1114                 } else
 1115                         val = 0;
 1116 
 1117                 if (val & (C3_CPUID_HAS_RNG | C3_CPUID_HAS_ACE))
 1118                         printf("%s:", ci->ci_dev.dv_xname);
 1119 
 1120                 /* Enable RNG if present and disabled */
 1121                 if (val & C3_CPUID_HAS_RNG) {
 1122                         extern int viac3_rnd_present;
 1123 
 1124                         if (!(val & C3_CPUID_DO_RNG)) {
 1125                                 msreg = rdmsr(0x110B);
 1126                                 msreg |= 0x40;
 1127                                 wrmsr(0x110B, msreg);
 1128                         }
 1129                         viac3_rnd_present = 1;
 1130                         printf(" RNG");
 1131                 }
 1132 
 1133                 /* Enable AES engine if present and disabled */
 1134                 if (val & C3_CPUID_HAS_ACE) {
 1135 #ifdef CRYPTO
 1136                         if (!(val & C3_CPUID_DO_ACE)) {
 1137                                 msreg = rdmsr(0x1107);
 1138                                 msreg |= (0x01 << 28);
 1139                                 wrmsr(0x1107, msreg);
 1140                         }
 1141                         i386_has_xcrypt |= C3_HAS_AES;
 1142 #endif /* CRYPTO */
 1143                         printf(" AES");
 1144                 }
 1145 
 1146                 /* Enable ACE2 engine if present and disabled */
 1147                 if (val & C3_CPUID_HAS_ACE2) {
 1148 #ifdef CRYPTO
 1149                         if (!(val & C3_CPUID_DO_ACE2)) {
 1150                                 msreg = rdmsr(0x1107);
 1151                                 msreg |= (0x01 << 28);
 1152                                 wrmsr(0x1107, msreg);
 1153                         }
 1154                         i386_has_xcrypt |= C3_HAS_AESCTR;
 1155 #endif /* CRYPTO */
 1156                         printf(" AES-CTR");
 1157                 }
 1158 
 1159                 /* Enable SHA engine if present and disabled */
 1160                 if (val & C3_CPUID_HAS_PHE) {
 1161 #ifdef CRYPTO
 1162                         if (!(val & C3_CPUID_DO_PHE)) {
 1163                                 msreg = rdmsr(0x1107);
 1164                                 msreg |= (0x01 << 28/**/);
 1165                                 wrmsr(0x1107, msreg);
 1166                         }
 1167                         i386_has_xcrypt |= C3_HAS_SHA;
 1168 #endif /* CRYPTO */
 1169                         printf(" SHA1 SHA256");
 1170                 }
 1171 
 1172                 /* Enable MM engine if present and disabled */
 1173                 if (val & C3_CPUID_HAS_PMM) {
 1174 #ifdef CRYPTO
 1175                         if (!(val & C3_CPUID_DO_PMM)) {
 1176                                 msreg = rdmsr(0x1107);
 1177                                 msreg |= (0x01 << 28/**/);
 1178                                 wrmsr(0x1107, msreg);
 1179                         }
 1180                         i386_has_xcrypt |= C3_HAS_MM;
 1181 #endif /* CRYPTO */
 1182                         printf(" RSA");
 1183                 }
 1184 
 1185                 printf("\n");
 1186                 break;
 1187         }
 1188 #endif
 1189 }
 1190 
 1191 void
 1192 cyrix6x86_cpu_setup(struct cpu_info *ci)
 1193 {
 1194         extern int clock_broken_latch;
 1195 
 1196         switch ((ci->ci_signature >> 4) & 15) { /* model */
 1197         case -1: /* M1 w/o cpuid */
 1198         case 2: /* M1 */
 1199                 /* set up various cyrix registers */
 1200                 /* Enable suspend on halt */
 1201                 cyrix_write_reg(0xc2, cyrix_read_reg(0xc2) | 0x08);
 1202                 /* enable access to ccr4/ccr5 */
 1203                 cyrix_write_reg(0xC3, cyrix_read_reg(0xC3) | 0x10);
 1204                 /* cyrix's workaround  for the "coma bug" */
 1205                 cyrix_write_reg(0x31, cyrix_read_reg(0x31) | 0xf8);
 1206                 cyrix_write_reg(0x32, cyrix_read_reg(0x32) | 0x7f);
 1207                 cyrix_write_reg(0x33, cyrix_read_reg(0x33) & ~0xff);
 1208                 cyrix_write_reg(0x3c, cyrix_read_reg(0x3c) | 0x87);
 1209                 /* disable access to ccr4/ccr5 */
 1210                 cyrix_write_reg(0xC3, cyrix_read_reg(0xC3) & ~0x10);
 1211 
 1212                 printf("%s: xchg bug workaround performed\n",
 1213                     ci->ci_dev.dv_xname);
 1214                 break;  /* fallthrough? */
 1215         case 4: /* GXm */
 1216                 /* Unset the TSC bit until calibrate_delay() gets fixed. */
 1217                 clock_broken_latch = 1;
 1218                 curcpu()->ci_feature_flags &= ~CPUID_TSC;
 1219                 printf("%s: TSC disabled\n", ci->ci_dev.dv_xname);
 1220                 break;
 1221         }
 1222 }
 1223 
 1224 void
 1225 natsem6x86_cpu_setup(struct cpu_info *ci)
 1226 {
 1227 #if defined(I586_CPU) || defined(I686_CPU)
 1228         extern int clock_broken_latch;
 1229         int model = (ci->ci_signature >> 4) & 15;
 1230 
 1231         clock_broken_latch = 1;
 1232         switch (model) {
 1233         case 4:
 1234                 cpu_feature &= ~CPUID_TSC;
 1235                 printf("%s: TSC disabled\n", ci->ci_dev.dv_xname);
 1236                 break;
 1237         }
 1238 #endif
 1239 }
 1240 
 1241 void
 1242 intel586_cpu_setup(struct cpu_info *ci)
 1243 {
 1244 #if defined(I586_CPU)
 1245         if (!cpu_f00f_bug) {
 1246                 fix_f00f();
 1247                 printf("%s: F00F bug workaround installed\n",
 1248                     ci->ci_dev.dv_xname);
 1249         }
 1250 #endif
 1251 }
 1252 
 1253 #if !defined(SMALL_KERNEL) && defined(I586_CPU)
 1254 void
 1255 amd_family5_setperf_setup(struct cpu_info *ci)
 1256 {
 1257         k6_powernow_init();
 1258 }
 1259 #endif
 1260 
 1261 void
 1262 amd_family5_setup(struct cpu_info *ci)
 1263 {
 1264         int model = (ci->ci_signature >> 4) & 15;
 1265 
 1266         switch (model) {
 1267         case 0:         /* AMD-K5 Model 0 */
 1268                 /*
 1269                  * According to the AMD Processor Recognition App Note,
 1270                  * the AMD-K5 Model 0 uses the wrong bit to indicate
 1271                  * support for global PTEs, instead using bit 9 (APIC)
 1272                  * rather than bit 13 (i.e. "0x200" vs. 0x2000".  Oops!).
 1273                  */
 1274                 if (cpu_feature & CPUID_APIC)
 1275                         cpu_feature = (cpu_feature & ~CPUID_APIC) | CPUID_PGE;
 1276                 /*
 1277                  * XXX But pmap_pg_g is already initialized -- need to kick
 1278                  * XXX the pmap somehow.  How does the MP branch do this?
 1279                  */
 1280                 break;
 1281         case 12:
 1282         case 13:
 1283 #if !defined(SMALL_KERNEL) && defined(I586_CPU)
 1284                 setperf_setup = amd_family5_setperf_setup;
 1285 #endif
 1286                 break;
 1287         }
 1288 }
 1289 
 1290 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
 1291 void
 1292 amd_family6_setperf_setup(struct cpu_info *ci)
 1293 {
 1294         int family = (ci->ci_signature >> 8) & 15;
 1295 
 1296         switch (family) {
 1297         case 6:
 1298                 k7_powernow_init();
 1299                 break;
 1300         case 15:
 1301                 k8_powernow_init();
 1302                 break;
 1303         }
 1304 }
 1305 #endif /* !SMALL_KERNEL && I686_CPU */
 1306 
 1307 void
 1308 amd_family6_setup(struct cpu_info *ci)
 1309 {
 1310 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
 1311         extern void (*pagezero)(void *, size_t);
 1312         extern void sse2_pagezero(void *, size_t);
 1313         extern void i686_pagezero(void *, size_t);
 1314 
 1315         if (cpu_feature & CPUID_SSE2)
 1316                 pagezero = sse2_pagezero;
 1317         else
 1318                 pagezero = i686_pagezero;
 1319 
 1320         setperf_setup = amd_family6_setperf_setup;
 1321 #endif
 1322 }
 1323 
 1324 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
 1325 /*
 1326  * Temperature read on the CPU is relative to the maximum
 1327  * temperature supported by the CPU, Tj(Max).
 1328  * Poorly documented, refer to:
 1329  * http://softwarecommunity.intel.com/isn/Community/
 1330  * en-US/forums/thread/30228638.aspx
 1331  * Basically, depending on a bit in one msr, the max is either 85 or 100.
 1332  * Then we subtract the temperature portion of thermal status from
 1333  * max to get current temperature.
 1334  */
 1335 void
 1336 intelcore_update_sensor(void *args)
 1337 {
 1338         struct cpu_info *ci = (struct cpu_info *) args;
 1339         u_int64_t msr;
 1340         int max = 100;
 1341 
 1342         if (rdmsr(MSR_TEMPERATURE_TARGET) & MSR_TEMPERATURE_TARGET_LOW_BIT)
 1343                 max = 85;
 1344 
 1345         msr = rdmsr(MSR_THERM_STATUS);
 1346         if (msr & MSR_THERM_STATUS_VALID_BIT) {
 1347                 ci->ci_sensor.value = max - MSR_THERM_STATUS_TEMP(msr);
 1348                 /* micro degrees */
 1349                 ci->ci_sensor.value *= 1000000;
 1350                 /* kelvin */
 1351                 ci->ci_sensor.value += 273150000;
 1352                 ci->ci_sensor.flags &= ~SENSOR_FINVALID;
 1353         } else {
 1354                 ci->ci_sensor.value = 0;
 1355                 ci->ci_sensor.flags |= SENSOR_FINVALID;
 1356         }
 1357 }
 1358 
 1359 void
 1360 intel686_cpusensors_setup(struct cpu_info *ci)
 1361 {
 1362         u_int regs[4];
 1363 
 1364         if (cpuid_level < 0x06)
 1365                 return;
 1366 
 1367         /* CPUID.06H.EAX[0] = 1 tells us if we have on-die sensor */
 1368         cpuid(0x06, regs);
 1369         if ((regs[0] & 0x01) != 1)
 1370                 return;
 1371 
 1372         /* Setup the sensors structures */
 1373         strlcpy(ci->ci_sensordev.xname, ci->ci_dev.dv_xname,
 1374             sizeof(ci->ci_sensordev.xname));
 1375         ci->ci_sensor.type = SENSOR_TEMP;
 1376         sensor_task_register(ci, intelcore_update_sensor, 5);
 1377         sensor_attach(&ci->ci_sensordev, &ci->ci_sensor);
 1378         sensordev_install(&ci->ci_sensordev);
 1379 }
 1380 #endif
 1381 
 1382 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
 1383 void
 1384 intel686_setperf_setup(struct cpu_info *ci)
 1385 {
 1386         int family = (ci->ci_signature >> 8) & 15;
 1387         int step = ci->ci_signature & 15;
 1388 
 1389         if (cpu_ecxfeature & CPUIDECX_EST) {
 1390                 if (rdmsr(MSR_MISC_ENABLE) & (1 << 16))
 1391                         est_init(ci->ci_dev.dv_xname, CPUVENDOR_INTEL);
 1392                 else
 1393                         printf("%s: Enhanced SpeedStep disabled by BIOS\n",
 1394                             ci->ci_dev.dv_xname);
 1395         } else if ((cpu_feature & (CPUID_ACPI | CPUID_TM)) ==
 1396             (CPUID_ACPI | CPUID_TM))
 1397                 p4tcc_init(family, step);
 1398 }
 1399 #endif
 1400 
 1401 void
 1402 intel686_common_cpu_setup(struct cpu_info *ci)
 1403 {
 1404 
 1405 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
 1406         setperf_setup = intel686_setperf_setup;
 1407         cpusensors_setup = intel686_cpusensors_setup;
 1408         {
 1409         extern void (*pagezero)(void *, size_t);
 1410         extern void sse2_pagezero(void *, size_t);
 1411         extern void i686_pagezero(void *, size_t);
 1412 
 1413         if (cpu_feature & CPUID_SSE2)
 1414                 pagezero = sse2_pagezero;
 1415         else
 1416                 pagezero = i686_pagezero;
 1417         }
 1418 #endif
 1419         /*
 1420          * Make sure SYSENTER is disabled.
 1421          */
 1422         if (cpu_feature & CPUID_SEP)
 1423                 wrmsr(MSR_SYSENTER_CS, 0);
 1424 }
 1425 
 1426 void
 1427 intel686_cpu_setup(struct cpu_info *ci)
 1428 {
 1429         int model = (ci->ci_signature >> 4) & 15;
 1430         int step = ci->ci_signature & 15;
 1431         u_quad_t msr119;
 1432 
 1433 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
 1434         p3_get_bus_clock(ci);
 1435 #endif
 1436 
 1437         intel686_common_cpu_setup(ci);
 1438 
 1439         /*
 1440          * Original PPro returns SYSCALL in CPUID but is non-functional.
 1441          * From Intel Application Note #485.
 1442          */
 1443         if ((model == 1) && (step < 3))
 1444                 ci->ci_feature_flags &= ~CPUID_SEP;
 1445 
 1446         /*
 1447          * Disable the Pentium3 serial number.
 1448          */
 1449         if ((model == 7) && (ci->ci_feature_flags & CPUID_SER)) {
 1450                 msr119 = rdmsr(MSR_BBL_CR_CTL);
 1451                 msr119 |= 0x0000000000200000LL;
 1452                 wrmsr(MSR_BBL_CR_CTL, msr119);
 1453 
 1454                 printf("%s: disabling processor serial number\n",
 1455                          ci->ci_dev.dv_xname);
 1456                 ci->ci_feature_flags &= ~CPUID_SER;
 1457                 ci->ci_level = 2;
 1458         }
 1459 
 1460 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
 1461         p3_early = (model == 8 && step == 1) ? 1 : 0;
 1462         update_cpuspeed = p3_update_cpuspeed;
 1463 #endif
 1464 }
 1465 
 1466 void
 1467 intel686_p4_cpu_setup(struct cpu_info *ci)
 1468 {
 1469 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
 1470         p4_get_bus_clock(ci);
 1471 #endif
 1472 
 1473         intel686_common_cpu_setup(ci);
 1474 
 1475 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
 1476         p4_model = (ci->ci_signature >> 4) & 15;
 1477         update_cpuspeed = p4_update_cpuspeed;
 1478 #endif
 1479 }
 1480 
 1481 void
 1482 tm86_cpu_setup(struct cpu_info *ci)
 1483 {
 1484 #if !defined(SMALL_KERNEL) && defined(I586_CPU)
 1485         longrun_init();
 1486 #endif
 1487 }
 1488 
 1489 char *
 1490 intel686_cpu_name(int model)
 1491 {
 1492         char *ret = NULL;
 1493 
 1494         switch (model) {
 1495         case 5:
 1496                 switch (cpu_cache_edx & 0xFF) {
 1497                 case 0x40:
 1498                 case 0x41:
 1499                         ret = "Celeron";
 1500                         break;
 1501                 /* 0x42 should not exist in this model. */
 1502                 case 0x43:
 1503                         ret = "Pentium II";
 1504                         break;
 1505                 case 0x44:
 1506                 case 0x45:
 1507                         ret = "Pentium II Xeon";
 1508                         break;
 1509                 }
 1510                 break;
 1511         case 7:
 1512                 switch (cpu_cache_edx & 0xFF) {
 1513                 /* 0x40 - 0x42 should not exist in this model. */
 1514                 case 0x43:
 1515                         ret = "Pentium III";
 1516                         break;
 1517                 case 0x44:
 1518                 case 0x45:
 1519                         ret = "Pentium III Xeon";
 1520                         break;
 1521                 }
 1522                 break;
 1523         }
 1524 
 1525         return (ret);
 1526 }
 1527 
 1528 char *
 1529 cyrix3_cpu_name(int model, int step)
 1530 {
 1531         char    *name = NULL;
 1532 
 1533         switch (model) {
 1534         case 7:
 1535                 if (step < 8)
 1536                         name = "C3 Samuel 2";
 1537                 else
 1538                         name = "C3 Ezra";
 1539                 break;
 1540         }
 1541         return name;
 1542 }
 1543 
 1544 /*
 1545  * Print identification for the given CPU.
 1546  * XXX XXX
 1547  * This is not as clean as one might like, because it references
 1548  *
 1549  * the "cpuid_level" and "cpu_vendor" globals.
 1550  * cpuid_level isn't so bad, since both CPU's will hopefully
 1551  * be of the same level.
 1552  *
 1553  * The Intel multiprocessor spec doesn't give us the cpu_vendor
 1554  * information; however, the chance of multi-vendor SMP actually
 1555  * ever *working* is sufficiently low that it's probably safe to assume
 1556  * all processors are of the same vendor.
 1557  */
 1558 
 1559 void
 1560 identifycpu(struct cpu_info *ci)
 1561 {
 1562         const char *name, *modifier, *vendorname, *token;
 1563         int class = CPUCLASS_386, vendor, i, max;
 1564         int family, model, step, modif, cachesize;
 1565         const struct cpu_cpuid_nameclass *cpup = NULL;
 1566         char *brandstr_from, *brandstr_to;
 1567         char *cpu_device = ci->ci_dev.dv_xname;
 1568         int skipspace;
 1569 
 1570         if (cpuid_level == -1) {
 1571 #ifdef DIAGNOSTIC
 1572                 if (cpu < 0 || cpu >=
 1573                     (sizeof i386_nocpuid_cpus/sizeof(struct cpu_nocpuid_nameclass)))
 1574                         panic("unknown cpu type %d", cpu);
 1575 #endif
 1576                 name = i386_nocpuid_cpus[cpu].cpu_name;
 1577                 vendor = i386_nocpuid_cpus[cpu].cpu_vendor;
 1578                 vendorname = i386_nocpuid_cpus[cpu].cpu_vendorname;
 1579                 model = -1;
 1580                 step = -1;
 1581                 class = i386_nocpuid_cpus[cpu].cpu_class;
 1582                 ci->cpu_setup = i386_nocpuid_cpus[cpu].cpu_setup;
 1583                 modifier = "";
 1584                 token = "";
 1585         } else {
 1586                 max = sizeof (i386_cpuid_cpus) / sizeof (i386_cpuid_cpus[0]);
 1587                 modif = (ci->ci_signature >> 12) & 3;
 1588                 family = (ci->ci_signature >> 8) & 15;
 1589                 model = (ci->ci_signature >> 4) & 15;
 1590                 step = ci->ci_signature & 15;
 1591 #ifdef CPUDEBUG
 1592                 printf("%s: family %x model %x step %x\n", cpu_device, family,
 1593                     model, step);
 1594                 printf("%s: cpuid level %d cache eax %x ebx %x ecx %x edx %x\n",
 1595                     cpu_device, cpuid_level, cpu_cache_eax, cpu_cache_ebx,
 1596                     cpu_cache_ecx, cpu_cache_edx);
 1597 #endif
 1598                 if (family < CPU_MINFAMILY)
 1599                         panic("identifycpu: strange family value");
 1600 
 1601                 for (i = 0; i < max; i++) {
 1602                         if (!strncmp(cpu_vendor,
 1603                             i386_cpuid_cpus[i].cpu_id, 12)) {
 1604                                 cpup = &i386_cpuid_cpus[i];
 1605                                 break;
 1606                         }
 1607                 }
 1608 
 1609                 if (cpup == NULL) {
 1610                         vendor = CPUVENDOR_UNKNOWN;
 1611                         if (cpu_vendor[0] != '\0')
 1612                                 vendorname = &cpu_vendor[0];
 1613                         else
 1614                                 vendorname = "Unknown";
 1615                         if (family > CPU_MAXFAMILY)
 1616                                 family = CPU_MAXFAMILY;
 1617                         class = family - 3;
 1618                         if (class > CPUCLASS_686)
 1619                                 class = CPUCLASS_686;
 1620                         modifier = "";
 1621                         name = "";
 1622                         token = "";
 1623                         ci->cpu_setup = NULL;
 1624                 } else {
 1625                         token = cpup->cpu_id;
 1626                         vendor = cpup->cpu_vendor;
 1627                         vendorname = cpup->cpu_vendorname;
 1628                         /*
 1629                          * Special hack for the VIA C3 series.
 1630                          *
 1631                          * VIA bought Centaur Technology from IDT in Aug 1999
 1632                          * and marketed the processors as VIA Cyrix III/C3.
 1633                          */
 1634                         if (vendor == CPUVENDOR_IDT && family >= 6) {
 1635                                 vendor = CPUVENDOR_VIA;
 1636                                 vendorname = "VIA";
 1637                         }
 1638                         modifier = modifiers[modif];
 1639                         if (family > CPU_MAXFAMILY) {
 1640                                 family = CPU_MAXFAMILY;
 1641                                 model = CPU_DEFMODEL;
 1642                         } else if (model > CPU_MAXMODEL)
 1643                                 model = CPU_DEFMODEL;
 1644                         i = family - CPU_MINFAMILY;
 1645 
 1646                         /* Special hack for the PentiumII/III series. */
 1647                         if (vendor == CPUVENDOR_INTEL && family == 6 &&
 1648                             (model == 5 || model == 7)) {
 1649                                 name = intel686_cpu_name(model);
 1650                         /* Special hack for the VIA C3 series. */
 1651                         } else if (vendor == CPUVENDOR_VIA && family == 6 &&
 1652                             model == 7) {
 1653                                 name = cyrix3_cpu_name(model, step);
 1654                         /* Special hack for the TMS5x00 series. */
 1655                         } else if (vendor == CPUVENDOR_TRANSMETA &&
 1656                             family == 5 && model == 4) {
 1657                                 name = tm86_cpu_name(model);
 1658                         } else
 1659                                 name = cpup->cpu_family[i].cpu_models[model];
 1660                         if (name == NULL) {
 1661                                 name = cpup->cpu_family[i].cpu_models[CPU_DEFMODEL];
 1662                                 if (name == NULL)
 1663                                         name = "";
 1664                         }
 1665                         class = cpup->cpu_family[i].cpu_class;
 1666                         ci->cpu_setup = cpup->cpu_family[i].cpu_setup;
 1667                 }
 1668         }
 1669 
 1670         /* Find the amount of on-chip L2 cache. */
 1671         cachesize = -1;
 1672         if (vendor == CPUVENDOR_INTEL && cpuid_level >= 2 && family < 0xf) {
 1673                 int intel_cachetable[] = { 0, 128, 256, 512, 1024, 2048 };
 1674 
 1675                 if ((cpu_cache_edx & 0xFF) >= 0x40 &&
 1676                     (cpu_cache_edx & 0xFF) <= 0x45)
 1677                         cachesize = intel_cachetable[(cpu_cache_edx & 0xFF) - 0x40];
 1678         } else if (vendor == CPUVENDOR_AMD && class == CPUCLASS_686) {
 1679                 u_int regs[4];
 1680                 cpuid(0x80000000, regs);
 1681                 if (regs[0] >= 0x80000006) {
 1682                         cpuid(0x80000006, regs);
 1683                         cachesize = (regs[2] >> 16);
 1684                 }
 1685         }
 1686 
 1687         /* Remove leading and duplicated spaces from cpu_brandstr */
 1688         brandstr_from = brandstr_to = cpu_brandstr;
 1689         skipspace = 1;
 1690         while (*brandstr_from != '\0') {
 1691                 if (!skipspace || *brandstr_from != ' ') {
 1692                         skipspace = 0;
 1693                         *(brandstr_to++) = *brandstr_from;
 1694                 }
 1695                 if (*brandstr_from == ' ')
 1696                         skipspace = 1;
 1697                 brandstr_from++;
 1698         }
 1699         *brandstr_to = '\0';
 1700 
 1701         if (cpu_brandstr[0] == '\0') {
 1702                 snprintf(cpu_brandstr, 48 /* sizeof(cpu_brandstr) */,
 1703                     "%s %s%s", vendorname, modifier, name);
 1704         }
 1705 
 1706         if ((ci->ci_flags & CPUF_PRIMARY) == 0) {
 1707                 if (cachesize > -1) {
 1708                         snprintf(cpu_model, sizeof(cpu_model),
 1709                             "%s (%s%s%s%s-class, %dKB L2 cache)",
 1710                             cpu_brandstr,
 1711                             ((*token) ? "\"" : ""), ((*token) ? token : ""),
 1712                             ((*token) ? "\" " : ""), classnames[class], cachesize);
 1713                 } else {
 1714                         snprintf(cpu_model, sizeof(cpu_model),
 1715                             "%s (%s%s%s%s-class)",
 1716                             cpu_brandstr,
 1717                             ((*token) ? "\"" : ""), ((*token) ? token : ""),
 1718                             ((*token) ? "\" " : ""), classnames[class]);
 1719                 }
 1720 
 1721                 printf("%s: %s", cpu_device, cpu_model);
 1722         }
 1723 
 1724 #if defined(I586_CPU) || defined(I686_CPU)
 1725         if (ci->ci_feature_flags && (ci->ci_feature_flags & CPUID_TSC)) {
 1726                 /* Has TSC */
 1727                 calibrate_cyclecounter();
 1728                 if (cpuspeed > 994) {
 1729                         int ghz, fr;
 1730 
 1731                         ghz = (cpuspeed + 9) / 1000;
 1732                         fr = ((cpuspeed + 9) / 10 ) % 100;
 1733                         if ((ci->ci_flags & CPUF_PRIMARY) == 0) {
 1734                                 if (fr)
 1735                                         printf(" %d.%02d GHz", ghz, fr);
 1736                                 else
 1737                                         printf(" %d GHz", ghz);
 1738                         }
 1739                 } else {
 1740                         if ((ci->ci_flags & CPUF_PRIMARY) == 0) {
 1741                                 printf(" %d MHz", cpuspeed);
 1742                         }
 1743                 }
 1744         }
 1745 #endif
 1746         if ((ci->ci_flags & CPUF_PRIMARY) == 0) {
 1747                 printf("\n");
 1748 
 1749                 if (ci->ci_feature_flags) {
 1750                         int numbits = 0;
 1751 
 1752                         printf("%s: ", cpu_device);
 1753                         max = sizeof(i386_cpuid_features) /
 1754                             sizeof(i386_cpuid_features[0]);
 1755                         for (i = 0; i < max; i++) {
 1756                                 if (ci->ci_feature_flags &
 1757                                     i386_cpuid_features[i].feature_bit) {
 1758                                         printf("%s%s", (numbits == 0 ? "" : ","),
 1759                                             i386_cpuid_features[i].feature_name);
 1760                                         numbits++;
 1761                                 }
 1762                         }
 1763                         max = sizeof(i386_cpuid_ecxfeatures)
 1764                                 / sizeof(i386_cpuid_ecxfeatures[0]);
 1765                         for (i = 0; i < max; i++) {
 1766                                 if (cpu_ecxfeature &
 1767                                     i386_cpuid_ecxfeatures[i].feature_bit) {
 1768                                         printf("%s%s", (numbits == 0 ? "" : ","),
 1769                                             i386_cpuid_ecxfeatures[i].feature_name);
 1770                                         numbits++;
 1771                                 }
 1772                         }
 1773                         printf("\n");
 1774                 }
 1775         }
 1776 
 1777 #ifndef MULTIPROCESSOR
 1778         /* configure the CPU if needed */
 1779         if (ci->cpu_setup != NULL)
 1780                 (ci->cpu_setup)(ci);
 1781 #endif
 1782 
 1783 #ifndef SMALL_KERNEL
 1784 #if defined(I586_CPU) || defined(I686_CPU)
 1785         if (cpuspeed != 0 && cpu_cpuspeed == NULL)
 1786                 cpu_cpuspeed = pentium_cpuspeed;
 1787 #endif
 1788 #endif
 1789 
 1790         cpu_class = class;
 1791 
 1792         /*
 1793          * Now that we have told the user what they have,
 1794          * let them know if that machine type isn't configured.
 1795          */
 1796         switch (cpu_class) {
 1797 #if !defined(I486_CPU) && !defined(I586_CPU) && !defined(I686_CPU)
 1798 #error No CPU classes configured.
 1799 #endif
 1800 #ifndef I686_CPU
 1801         case CPUCLASS_686:
 1802                 printf("NOTICE: this kernel does not support Pentium Pro CPU class\n");
 1803 #ifdef I586_CPU
 1804                 printf("NOTICE: lowering CPU class to i586\n");
 1805                 cpu_class = CPUCLASS_586;
 1806                 break;
 1807 #endif
 1808 #endif
 1809 #ifndef I586_CPU
 1810         case CPUCLASS_586:
 1811                 printf("NOTICE: this kernel does not support Pentium CPU class\n");
 1812 #ifdef I486_CPU
 1813                 printf("NOTICE: lowering CPU class to i486\n");
 1814                 cpu_class = CPUCLASS_486;
 1815                 break;
 1816 #endif
 1817 #endif
 1818 #ifndef I486_CPU
 1819         case CPUCLASS_486:
 1820                 printf("NOTICE: this kernel does not support i486 CPU class\n");
 1821 #endif
 1822         case CPUCLASS_386:
 1823                 printf("NOTICE: this kernel does not support i386 CPU class\n");
 1824                 panic("no appropriate CPU class available");
 1825         default:
 1826                 break;
 1827         }
 1828 
 1829         ci->cpu_class = class;
 1830 
 1831         if (cpu == CPU_486DLC) {
 1832 #ifndef CYRIX_CACHE_WORKS
 1833                 printf("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n");
 1834 #else
 1835 #ifndef CYRIX_CACHE_REALLY_WORKS
 1836                 printf("WARNING: CYRIX 486DLC CACHE ENABLED IN HOLD-FLUSH MODE.\n");
 1837 #else
 1838                 printf("WARNING: CYRIX 486DLC CACHE ENABLED.\n");
 1839 #endif
 1840 #endif
 1841         }
 1842 
 1843         /*
 1844          * Enable ring 0 write protection (486 or above, but 386
 1845          * no longer supported).
 1846          */
 1847         lcr0(rcr0() | CR0_WP);
 1848 
 1849 #if defined(I686_CPU)
 1850         /*
 1851          * If we have FXSAVE/FXRESTOR, use them.
 1852          */
 1853         if (cpu_feature & CPUID_FXSR) {
 1854                 i386_use_fxsave = 1;
 1855                 lcr4(rcr4() | CR4_OSFXSR);
 1856 
 1857                 /*
 1858                  * If we have SSE/SSE2, enable XMM exceptions, and
 1859                  * notify userland.
 1860                  */
 1861                 if (cpu_feature & (CPUID_SSE|CPUID_SSE2)) {
 1862                         if (cpu_feature & CPUID_SSE)
 1863                                 i386_has_sse = 1;
 1864                         if (cpu_feature & CPUID_SSE2)
 1865                                 i386_has_sse2 = 1;
 1866                         lcr4(rcr4() | CR4_OSXMMEXCPT);
 1867                 }
 1868         } else
 1869                 i386_use_fxsave = 0;
 1870 
 1871         if (vendor == CPUVENDOR_AMD)
 1872                 amd64_errata(ci);
 1873 #endif /* I686_CPU */
 1874 }
 1875 
 1876 char *
 1877 tm86_cpu_name(int model)
 1878 {
 1879         u_int32_t regs[4];
 1880         char *name = NULL;
 1881 
 1882         cpuid(0x80860001, regs);
 1883 
 1884         switch (model) {
 1885         case 4:
 1886                 if (((regs[1] >> 16) & 0xff) >= 0x3)
 1887                         name = "TMS5800";
 1888                 else
 1889                         name = "TMS5600";
 1890         }
 1891 
 1892         return name;
 1893 }
 1894 
 1895 #ifndef SMALL_KERNEL
 1896 #ifdef I686_CPU
 1897 void
 1898 cyrix3_get_bus_clock(struct cpu_info *ci)
 1899 {
 1900         u_int64_t msr;
 1901         int bus;
 1902 
 1903         msr = rdmsr(MSR_EBL_CR_POWERON);
 1904         bus = (msr >> 18) & 0x3;
 1905         switch (bus) {
 1906         case 0:
 1907                 bus_clock = BUS100;
 1908                 break;
 1909         case 1:
 1910                 bus_clock = BUS133;
 1911                 break;
 1912         case 2:
 1913                 bus_clock = BUS200;
 1914                 break;
 1915         case 3:
 1916                 bus_clock = BUS166;
 1917                 break;
 1918         }
 1919 }
 1920 
 1921 void
 1922 p4_get_bus_clock(struct cpu_info *ci)
 1923 {
 1924         u_int64_t msr;
 1925         int model, bus;
 1926 
 1927         model = (ci->ci_signature >> 4) & 15;
 1928         msr = rdmsr(MSR_EBC_FREQUENCY_ID);
 1929         if (model < 2) {
 1930                 bus = (msr >> 21) & 0x7;
 1931                 switch (bus) {
 1932                 case 0:
 1933                         bus_clock = BUS100;
 1934                         break;
 1935                 case 1:
 1936                         bus_clock = BUS133;
 1937                         break;
 1938                 default:
 1939                         printf("%s: unknown Pentium 4 (model %d) "
 1940                             "EBC_FREQUENCY_ID value %d\n",
 1941                             ci->ci_dev.dv_xname, model, bus);
 1942                         break;
 1943                 }
 1944         } else {
 1945                 bus = (msr >> 16) & 0x7;
 1946                 switch (bus) {
 1947                 case 0:
 1948                         bus_clock = (model == 2) ? BUS100 : BUS266;
 1949                         break;
 1950                 case 1:
 1951                         bus_clock = BUS133;
 1952                         break;
 1953                 case 2:
 1954                         bus_clock = BUS200;
 1955                         break;
 1956                 case 3:
 1957                         bus_clock = BUS166;
 1958                         break;
 1959                 default:
 1960                         printf("%s: unknown Pentium 4 (model %d) "
 1961                             "EBC_FREQUENCY_ID value %d\n",
 1962                             ci->ci_dev.dv_xname, model, bus);
 1963                         break;
 1964                 }
 1965         }
 1966 }
 1967 
 1968 void
 1969 p3_get_bus_clock(struct cpu_info *ci)
 1970 {
 1971         u_int64_t msr;
 1972         int model, bus;
 1973 
 1974         model = (ci->ci_signature >> 4) & 15;
 1975         switch (model) {
 1976         case 0x9: /* Pentium M (130 nm, Banias) */
 1977                 bus_clock = BUS100;
 1978                 break;
 1979         case 0xd: /* Pentium M (90 nm, Dothan) */
 1980                 msr = rdmsr(MSR_FSB_FREQ);
 1981                 bus = (msr >> 0) & 0x7;
 1982                 switch (bus) {
 1983                 case 0:
 1984                         bus_clock = BUS100;
 1985                         break;
 1986                 case 1:
 1987                         bus_clock = BUS133;
 1988                         break;
 1989                 default:
 1990                         printf("%s: unknown Pentium M FSB_FREQ value %d",
 1991                             ci->ci_dev.dv_xname, bus);
 1992                         goto print_msr;
 1993                 }
 1994                 break;
 1995         case 0xe: /* Core Duo/Solo */
 1996         case 0xf: /* Core Xeon */
 1997                 msr = rdmsr(MSR_FSB_FREQ);
 1998                 bus = (msr >> 0) & 0x7;
 1999                 switch (bus) {
 2000                 case 5:
 2001                         bus_clock = BUS100;
 2002                         break;
 2003                 case 1:
 2004                         bus_clock = BUS133;
 2005                         break;
 2006                 case 3:
 2007                         bus_clock = BUS166;
 2008                         break;
 2009                 case 2:
 2010                         bus_clock = BUS200;
 2011                         break;
 2012                 case 0:
 2013                         bus_clock = BUS266;
 2014                         break;
 2015                 case 4:
 2016                         bus_clock = BUS333;
 2017                         break;
 2018                 default:
 2019                         printf("%s: unknown Core FSB_FREQ value %d",
 2020                             ci->ci_dev.dv_xname, bus);
 2021                         goto print_msr;
 2022                 }
 2023                 break;
 2024         case 0x1: /* Pentium Pro, model 1 */
 2025         case 0x3: /* Pentium II, model 3 */
 2026         case 0x5: /* Pentium II, II Xeon, Celeron, model 5 */
 2027         case 0x6: /* Celeron, model 6 */
 2028         case 0x7: /* Pentium III, III Xeon, model 7 */
 2029         case 0x8: /* Pentium III, III Xeon, Celeron, model 8 */
 2030         case 0xa: /* Pentium III Xeon, model A */
 2031         case 0xb: /* Pentium III, model B */
 2032                 msr = rdmsr(MSR_EBL_CR_POWERON);
 2033                 bus = (msr >> 18) & 0x3;
 2034                 switch (bus) {
 2035                 case 0:
 2036                         bus_clock = BUS66;
 2037                         break;
 2038                 case 1:
 2039                         bus_clock = BUS133;
 2040                         break;
 2041                 case 2:
 2042                         bus_clock = BUS100;
 2043                         break;
 2044                 default:
 2045                         printf("%s: unknown i686 EBL_CR_POWERON value %d",
 2046                             ci->ci_dev.dv_xname, bus);
 2047                         goto print_msr;
 2048                 }
 2049                 break;
 2050         default: 
 2051                 printf("%s: unknown i686 model %d, can't get bus clock",
 2052                     ci->ci_dev.dv_xname, model);
 2053 print_msr:
 2054                 /*
 2055                  * Show the EBL_CR_POWERON MSR, so we'll at least have
 2056                  * some extra information, such as clock ratio, etc.
 2057                  */
 2058                 printf(" (0x%llx)\n", rdmsr(MSR_EBL_CR_POWERON));
 2059                 break;
 2060         }
 2061 }
 2062 
 2063 void
 2064 p4_update_cpuspeed(void)
 2065 {
 2066         u_int64_t msr;
 2067         int mult;
 2068 
 2069         if (bus_clock == 0) {
 2070                 printf("p4_update_cpuspeed: unknown bus clock\n");
 2071                 return;
 2072         }
 2073 
 2074         msr = rdmsr(MSR_EBC_FREQUENCY_ID);
 2075         mult = ((msr >> 24) & 0xff);
 2076 
 2077         cpuspeed = (bus_clock * mult) / 100;
 2078 }
 2079 
 2080 void
 2081 p3_update_cpuspeed(void)
 2082 {
 2083         u_int64_t msr;
 2084         int mult;
 2085         const u_int8_t mult_code[] = {
 2086             50, 30, 40, 0, 55, 35, 45, 0, 0, 70, 80, 60, 0, 75, 0, 65 };
 2087 
 2088         if (bus_clock == 0) {
 2089                 printf("p3_update_cpuspeed: unknown bus clock\n");
 2090                 return;
 2091         }
 2092 
 2093         msr = rdmsr(MSR_EBL_CR_POWERON);
 2094         mult = (msr >> 22) & 0xf;
 2095         mult = mult_code[mult];
 2096         if (!p3_early)
 2097                 mult += ((msr >> 27) & 0x1) * 40;
 2098 
 2099         cpuspeed = (bus_clock * mult) / 1000;
 2100 }
 2101 #endif  /* I686_CPU */
 2102 
 2103 #if defined(I586_CPU) || defined(I686_CPU)
 2104 int
 2105 pentium_cpuspeed(int *freq)
 2106 {
 2107         *freq = cpuspeed;
 2108         return (0);
 2109 }
 2110 #endif
 2111 #endif  /* !SMALL_KERNEL */
 2112 
 2113 #ifdef COMPAT_IBCS2
 2114 void ibcs2_sendsig(sig_t, int, int, u_long, int, union sigval);
 2115 
 2116 void
 2117 ibcs2_sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
 2118     union sigval val)
 2119 {
 2120         extern int bsd_to_ibcs2_sig[];
 2121 
 2122         sendsig(catcher, bsd_to_ibcs2_sig[sig], mask, code, type, val);
 2123 }
 2124 #endif
 2125 
 2126 /*
 2127  * To send an AST to a process on another cpu we send an IPI to that cpu,
 2128  * the IPI schedules a special soft interrupt (that does nothing) and then
 2129  * returns through the normal interrupt return path which in turn handles
 2130  * the AST.
 2131  *
 2132  * The IPI can't handle the AST because it usually requires grabbing the
 2133  * biglock and we can't afford spinning in the IPI handler with interrupts
 2134  * unlocked (so that we take further IPIs and grow our stack until it
 2135  * overflows).
 2136  */
 2137 void
 2138 aston(struct proc *p)
 2139 {
 2140 #ifdef MULTIPROCESSOR
 2141         if (i386_atomic_testset_i(&p->p_md.md_astpending, 1) == 0 &&
 2142             p->p_cpu != curcpu())
 2143                 i386_fast_ipi(p->p_cpu, LAPIC_IPI_AST);
 2144 #else
 2145         p->p_md.md_astpending = 1;
 2146 #endif
 2147 }
 2148 
 2149 /*
 2150  * Send an interrupt to process.
 2151  *
 2152  * Stack is set up to allow sigcode stored
 2153  * in u. to call routine, followed by kcall
 2154  * to sigreturn routine below.  After sigreturn
 2155  * resets the signal mask, the stack, and the
 2156  * frame pointer, it returns to the user
 2157  * specified pc, psl.
 2158  */
 2159 void
 2160 sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
 2161     union sigval val)
 2162 {
 2163 #ifdef I686_CPU
 2164         extern char sigcode, sigcode_xmm;
 2165 #endif
 2166         struct proc *p = curproc;
 2167         struct trapframe *tf = p->p_md.md_regs;
 2168         struct sigframe *fp, frame;
 2169         struct sigacts *psp = p->p_sigacts;
 2170         register_t sp;
 2171         int oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
 2172 
 2173         /*
 2174          * Build the argument list for the signal handler.
 2175          */
 2176         frame.sf_signum = sig;
 2177 
 2178         /*
 2179          * Allocate space for the signal handler context.
 2180          */
 2181         if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
 2182             (psp->ps_sigonstack & sigmask(sig))) {
 2183                 sp = (long)psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size;
 2184                 psp->ps_sigstk.ss_flags |= SS_ONSTACK;
 2185         } else
 2186                 sp = tf->tf_esp;
 2187 
 2188         frame.sf_fpstate = NULL;
 2189         if (p->p_md.md_flags & MDP_USEDFPU) {
 2190                 sp -= sizeof(union savefpu);
 2191                 sp &= ~0xf;     /* foe XMM regs */
 2192                 frame.sf_fpstate = (void *)sp;
 2193         }
 2194 
 2195         fp = (struct sigframe *)sp - 1;
 2196         frame.sf_scp = &fp->sf_sc;
 2197         frame.sf_sip = NULL;
 2198         frame.sf_handler = catcher;
 2199 
 2200         /*
 2201          * Build the signal context to be used by sigreturn.
 2202          */
 2203         frame.sf_sc.sc_err = tf->tf_err;
 2204         frame.sf_sc.sc_trapno = tf->tf_trapno;
 2205         frame.sf_sc.sc_onstack = oonstack;
 2206         frame.sf_sc.sc_mask = mask;
 2207 #ifdef VM86
 2208         if (tf->tf_eflags & PSL_VM) {
 2209                 frame.sf_sc.sc_gs = tf->tf_vm86_gs;
 2210                 frame.sf_sc.sc_fs = tf->tf_vm86_fs;
 2211                 frame.sf_sc.sc_es = tf->tf_vm86_es;
 2212                 frame.sf_sc.sc_ds = tf->tf_vm86_ds;
 2213                 frame.sf_sc.sc_eflags = get_vflags(p);
 2214         } else
 2215 #endif
 2216         {
 2217                 frame.sf_sc.sc_fs = tf->tf_fs;
 2218                 frame.sf_sc.sc_gs = tf->tf_gs;
 2219                 frame.sf_sc.sc_es = tf->tf_es;
 2220                 frame.sf_sc.sc_ds = tf->tf_ds;
 2221                 frame.sf_sc.sc_eflags = tf->tf_eflags;
 2222         }
 2223         frame.sf_sc.sc_edi = tf->tf_edi;
 2224         frame.sf_sc.sc_esi = tf->tf_esi;
 2225         frame.sf_sc.sc_ebp = tf->tf_ebp;
 2226         frame.sf_sc.sc_ebx = tf->tf_ebx;
 2227         frame.sf_sc.sc_edx = tf->tf_edx;
 2228         frame.sf_sc.sc_ecx = tf->tf_ecx;
 2229         frame.sf_sc.sc_eax = tf->tf_eax;
 2230         frame.sf_sc.sc_eip = tf->tf_eip;
 2231         frame.sf_sc.sc_cs = tf->tf_cs;
 2232         frame.sf_sc.sc_esp = tf->tf_esp;
 2233         frame.sf_sc.sc_ss = tf->tf_ss;
 2234 
 2235         if (psp->ps_siginfo & sigmask(sig)) {
 2236                 frame.sf_sip = &fp->sf_si;
 2237                 initsiginfo(&frame.sf_si, sig, code, type, val);
 2238 #ifdef VM86
 2239                 if (sig == SIGURG)      /* VM86 userland trap */
 2240                         frame.sf_si.si_trapno = code;
 2241 #endif
 2242         }
 2243 
 2244         /* XXX don't copyout siginfo if not needed? */
 2245         if (copyout(&frame, fp, sizeof(frame)) != 0) {
 2246                 /*
 2247                  * Process has trashed its stack; give it an illegal
 2248                  * instruction to halt it in its tracks.
 2249                  */
 2250                 sigexit(p, SIGILL);
 2251                 /* NOTREACHED */
 2252         }
 2253 
 2254         /*
 2255          * Build context to run handler in.
 2256          */
 2257         tf->tf_fs = GSEL(GUDATA_SEL, SEL_UPL);
 2258         tf->tf_gs = GSEL(GUDATA_SEL, SEL_UPL);
 2259         tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
 2260         tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
 2261         tf->tf_eip = p->p_sigcode;
 2262         tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
 2263 #ifdef I686_CPU
 2264         if (i386_use_fxsave)
 2265                 tf->tf_eip += &sigcode_xmm - &sigcode;
 2266 #endif
 2267         tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
 2268         tf->tf_esp = (int)fp;
 2269         tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
 2270 }
 2271 
 2272 /*
 2273  * System call to cleanup state after a signal
 2274  * has been taken.  Reset signal mask and
 2275  * stack state from context left by sendsig (above).
 2276  * Return to previous pc and psl as specified by
 2277  * context left by sendsig. Check carefully to
 2278  * make sure that the user has not modified the
 2279  * psl to gain improper privileges or to cause
 2280  * a machine fault.
 2281  */
 2282 int
 2283 sys_sigreturn(struct proc *p, void *v, register_t *retval)
 2284 {
 2285         struct sys_sigreturn_args /* {
 2286                 syscallarg(struct sigcontext *) sigcntxp;
 2287         } */ *uap = v;
 2288         struct sigcontext *scp, context;
 2289         struct trapframe *tf;
 2290 
 2291         tf = p->p_md.md_regs;
 2292 
 2293         /*
 2294          * The trampoline code hands us the context.
 2295          * It is unsafe to keep track of it ourselves, in the event that a
 2296          * program jumps out of a signal handler.
 2297          */
 2298         scp = SCARG(uap, sigcntxp);
 2299         if (copyin((caddr_t)scp, &context, sizeof(*scp)) != 0)
 2300                 return (EFAULT);
 2301 
 2302         /*
 2303          * Restore signal context.
 2304          */
 2305 #ifdef VM86
 2306         if (context.sc_eflags & PSL_VM) {
 2307                 tf->tf_vm86_gs = context.sc_gs;
 2308                 tf->tf_vm86_fs = context.sc_fs;
 2309                 tf->tf_vm86_es = context.sc_es;
 2310                 tf->tf_vm86_ds = context.sc_ds;
 2311                 set_vflags(p, context.sc_eflags);
 2312         } else
 2313 #endif
 2314         {
 2315                 /*
 2316                  * Check for security violations.  If we're returning to
 2317                  * protected mode, the CPU will validate the segment registers
 2318                  * automatically and generate a trap on violations.  We handle
 2319                  * the trap, rather than doing all of the checking here.
 2320                  */
 2321                 if (((context.sc_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
 2322                     !USERMODE(context.sc_cs, context.sc_eflags))
 2323                         return (EINVAL);
 2324 
 2325                 tf->tf_fs = context.sc_fs;
 2326                 tf->tf_gs = context.sc_gs;
 2327                 tf->tf_es = context.sc_es;
 2328                 tf->tf_ds = context.sc_ds;
 2329                 tf->tf_eflags = context.sc_eflags;
 2330         }
 2331         tf->tf_edi = context.sc_edi;
 2332         tf->tf_esi = context.sc_esi;
 2333         tf->tf_ebp = context.sc_ebp;
 2334         tf->tf_ebx = context.sc_ebx;
 2335         tf->tf_edx = context.sc_edx;
 2336         tf->tf_ecx = context.sc_ecx;
 2337         tf->tf_eax = context.sc_eax;
 2338         tf->tf_eip = context.sc_eip;
 2339         tf->tf_cs = context.sc_cs;
 2340         tf->tf_esp = context.sc_esp;
 2341         tf->tf_ss = context.sc_ss;
 2342 
 2343         if (context.sc_onstack & 01)
 2344                 p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
 2345         else
 2346                 p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
 2347         p->p_sigmask = context.sc_mask & ~sigcantmask;
 2348 
 2349         return (EJUSTRETURN);
 2350 }
 2351 
 2352 int     waittime = -1;
 2353 struct pcb dumppcb;
 2354 
 2355 void
 2356 boot(int howto)
 2357 {
 2358         if (cold) {
 2359                 /*
 2360                  * If the system is cold, just halt, unless the user
 2361                  * explicitly asked for reboot.
 2362                  */
 2363                 if ((howto & RB_USERREQ) == 0)
 2364                         howto |= RB_HALT;
 2365                 goto haltsys;
 2366         }
 2367 
 2368         boothowto = howto;
 2369         if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
 2370                 extern struct proc proc0;
 2371 
 2372                 /* protect against curproc->p_stats.foo refs in sync()   XXX */
 2373                 if (curproc == NULL)
 2374                         curproc = &proc0;
 2375 
 2376                 waittime = 0;
 2377                 vfs_shutdown();
 2378                 /*
 2379                  * If we've been adjusting the clock, the todr
 2380                  * will be out of synch; adjust it now.
 2381                  */
 2382                 if ((howto & RB_TIMEBAD) == 0) {
 2383                         resettodr();
 2384                 } else {
 2385                         printf("WARNING: not updating battery clock\n");
 2386                 }
 2387         }
 2388 
 2389         /* Disable interrupts. */
 2390         splhigh();
 2391 
 2392         /* Do a dump if requested. */
 2393         if (howto & RB_DUMP)
 2394                 dumpsys();
 2395 
 2396 haltsys:
 2397         doshutdownhooks();
 2398 
 2399         if (howto & RB_HALT) {
 2400 #if NACPI > 0 && !defined(SMALL_KERNEL)
 2401                 extern int acpi_s5, acpi_enabled;
 2402 
 2403                 if (acpi_enabled) {
 2404                         delay(500000);
 2405                         if ((howto & RB_POWERDOWN) || acpi_s5)
 2406                                 acpi_powerdown();
 2407                 }
 2408 #endif
 2409 
 2410 #if NAPM > 0
 2411                 if (howto & RB_POWERDOWN) {
 2412                         int rv;
 2413 
 2414                         printf("\nAttempting to power down...\n");
 2415                         /*
 2416                          * Turn off, if we can.  But try to turn disk off and
 2417                          * wait a bit first--some disk drives are slow to
 2418                          * clean up and users have reported disk corruption.
 2419                          *
 2420                          * If apm_set_powstate() fails the first time, don't
 2421                          * try to turn the system off.
 2422                          */
 2423                         delay(500000);
 2424                         /*
 2425                          * It's been reported that the following bit of code
 2426                          * is required on most systems <mickey@openbsd.org>
 2427                          * but cause powerdown problem on other systems
 2428                          * <smcho@tsp.korea.ac.kr>.  Use sysctl to set
 2429                          * apmhalt to a non-zero value to skip the offending
 2430                          * code.
 2431                          */
 2432                         if (!cpu_apmhalt) {
 2433                                 apm_set_powstate(APM_DEV_DISK(0xff),
 2434                                                  APM_SYS_OFF);
 2435                                 delay(500000);
 2436                         }
 2437                         rv = apm_set_powstate(APM_DEV_DISK(0xff), APM_SYS_OFF);
 2438                         if (rv == 0 || rv == ENXIO) {
 2439                                 delay(500000);
 2440                                 (void) apm_set_powstate(APM_DEV_ALLDEVS,
 2441                                                         APM_SYS_OFF);
 2442                         }
 2443                 }
 2444 #endif
 2445                 printf("\n");
 2446                 printf("The operating system has halted.\n");
 2447                 printf("Please press any key to reboot.\n\n");
 2448                 cngetc();
 2449         }
 2450 
 2451         printf("rebooting...\n");
 2452         cpu_reset();
 2453         for(;;) ;
 2454         /*NOTREACHED*/
 2455 }
 2456 
 2457 /*
 2458  * This is called by configure to set dumplo and dumpsize.
 2459  * Dumps always skip the first block of disk space
 2460  * in case there might be a disk label stored there.
 2461  * If there is extra space, put dump at the end to
 2462  * reduce the chance that swapping trashes it.
 2463  */
 2464 void
 2465 dumpconf(void)
 2466 {
 2467         int nblks;      /* size of dump area */
 2468         int i;
 2469 
 2470         if (dumpdev == NODEV ||
 2471             (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
 2472                 return;
 2473         if (nblks <= ctod(1))
 2474                 return;
 2475 
 2476         /* Always skip the first block, in case there is a label there. */
 2477         if (dumplo < ctod(1))
 2478                 dumplo = ctod(1);
 2479 
 2480         for (i = 0; i < ndumpmem; i++)
 2481                 dumpsize = max(dumpsize, dumpmem[i].end);
 2482 
 2483         /* Put dump at end of partition, and make it fit. */
 2484         if (dumpsize > dtoc(nblks - dumplo - 1))
 2485                 dumpsize = dtoc(nblks - dumplo - 1);
 2486         if (dumplo < nblks - ctod(dumpsize) - 1)
 2487                 dumplo = nblks - ctod(dumpsize) - 1;
 2488 }
 2489 
 2490 /*
 2491  * cpu_dump: dump machine-dependent kernel core dump headers.
 2492  */
 2493 int
 2494 cpu_dump()
 2495 {
 2496         int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
 2497         long buf[dbtob(1) / sizeof (long)];
 2498         kcore_seg_t     *segp;
 2499 
 2500         dump = bdevsw[major(dumpdev)].d_dump;
 2501 
 2502         segp = (kcore_seg_t *)buf;
 2503 
 2504         /*
 2505          * Generate a segment header.
 2506          */
 2507         CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
 2508         segp->c_size = dbtob(1) - ALIGN(sizeof(*segp));
 2509 
 2510         return (dump(dumpdev, dumplo, (caddr_t)buf, dbtob(1)));
 2511 }
 2512 
 2513 /*
 2514  * Doadump comes here after turning off memory management and
 2515  * getting on the dump stack, either when called above, or by
 2516  * the auto-restart code.
 2517  */
 2518 static vaddr_t dumpspace;
 2519 
 2520 vaddr_t
 2521 reserve_dumppages(vaddr_t p)
 2522 {
 2523 
 2524         dumpspace = p;
 2525         return (p + PAGE_SIZE);
 2526 }
 2527 
 2528 void
 2529 dumpsys()
 2530 {
 2531         u_int i, j, npg;
 2532         int maddr;
 2533         daddr64_t blkno;
 2534         int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
 2535         int error;
 2536         char *str;
 2537         extern int msgbufmapped;
 2538 
 2539         /* Save registers. */
 2540         savectx(&dumppcb);
 2541 
 2542         msgbufmapped = 0;       /* don't record dump msgs in msgbuf */
 2543         if (dumpdev == NODEV)
 2544                 return;
 2545 
 2546         /*
 2547          * For dumps during autoconfiguration,
 2548          * if dump device has already configured...
 2549          */
 2550         if (dumpsize == 0)
 2551                 dumpconf();
 2552         if (dumplo < 0)
 2553                 return;
 2554         printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo);
 2555 
 2556         error = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
 2557         printf("dump ");
 2558         if (error == -1) {
 2559                 printf("area unavailable\n");
 2560                 return;
 2561         }
 2562 
 2563 #if 0   /* XXX this doesn't work.  grr. */
 2564         /* toss any characters present prior to dump */
 2565         while (sget() != NULL); /*syscons and pccons differ */
 2566 #endif
 2567 
 2568         /* scan through the dumpmem list */
 2569         dump = bdevsw[major(dumpdev)].d_dump;
 2570         error = cpu_dump();
 2571         for (i = 0; !error && i < ndumpmem; i++) {
 2572 
 2573                 npg = dumpmem[i].end - dumpmem[i].start;
 2574                 maddr = ctob(dumpmem[i].start);
 2575                 blkno = dumplo + btodb(maddr) + 1;
 2576 #if 0
 2577                 printf("(%d %lld %d) ", maddr, blkno, npg);
 2578 #endif
 2579                 for (j = npg; j--; maddr += NBPG, blkno += btodb(NBPG)) {
 2580 
 2581                         /* Print out how many MBs we have more to go. */
 2582                         if (dbtob(blkno - dumplo) % (1024 * 1024) < NBPG)
 2583                                 printf("%d ",
 2584                                     (ctob(dumpsize) - maddr) / (1024 * 1024));
 2585 #if 0
 2586                         printf("(%x %lld) ", maddr, blkno);
 2587 #endif
 2588                         pmap_enter(pmap_kernel(), dumpspace, maddr,
 2589                             VM_PROT_READ, PMAP_WIRED);
 2590                         if ((error = (*dump)(dumpdev, blkno,
 2591                             (caddr_t)dumpspace, NBPG)))
 2592                                 break;
 2593 
 2594 #if 0   /* XXX this doesn't work.  grr. */
 2595                         /* operator aborting dump? */
 2596                         if (sget() != NULL) {
 2597                                 error = EINTR;
 2598                                 break;
 2599                         }
 2600 #endif
 2601                 }
 2602         }
 2603 
 2604         switch (error) {
 2605 
 2606         case 0:         str = "succeeded\n\n";                  break;
 2607         case ENXIO:     str = "device bad\n\n";                 break;
 2608         case EFAULT:    str = "device not ready\n\n";           break;
 2609         case EINVAL:    str = "area improper\n\n";              break;
 2610         case EIO:       str = "i/o error\n\n";                  break;
 2611         case EINTR:     str = "aborted from console\n\n";       break;
 2612         default:        str = "error %d\n\n";                   break;
 2613         }
 2614         printf(str, error);
 2615 
 2616         delay(5000000);         /* 5 seconds */
 2617 }
 2618 
 2619 /*
 2620  * Clear registers on exec
 2621  */
 2622 void
 2623 setregs(struct proc *p, struct exec_package *pack, u_long stack,
 2624     register_t *retval)
 2625 {
 2626         struct pcb *pcb = &p->p_addr->u_pcb;
 2627         struct pmap *pmap = vm_map_pmap(&p->p_vmspace->vm_map);
 2628         struct trapframe *tf = p->p_md.md_regs;
 2629 
 2630 #if NNPX > 0
 2631         /* If we were using the FPU, forget about it. */
 2632         if (pcb->pcb_fpcpu != NULL)
 2633                 npxsave_proc(p, 0);
 2634 #endif
 2635 
 2636 #ifdef USER_LDT
 2637         pmap_ldt_cleanup(p);
 2638 #endif
 2639 
 2640         /*
 2641          * Reset the code segment limit to I386_MAX_EXE_ADDR in the pmap;
 2642          * this gets copied into the GDT and LDT for {G,L}UCODE_SEL by
 2643          * pmap_activate().
 2644          */
 2645         setsegment(&pmap->pm_codeseg, 0, atop(I386_MAX_EXE_ADDR) - 1,
 2646             SDT_MEMERA, SEL_UPL, 1, 1);
 2647 
 2648         /*
 2649          * And update the GDT and LDT since we return to the user process
 2650          * by leaving the syscall (we don't do another pmap_activate()).
 2651          */
 2652         curcpu()->ci_gdt[GUCODE_SEL].sd = pcb->pcb_ldt[LUCODE_SEL].sd =
 2653             pmap->pm_codeseg;
 2654 
 2655         /*
 2656          * And reset the hiexec marker in the pmap.
 2657          */
 2658         pmap->pm_hiexec = 0;
 2659 
 2660         p->p_md.md_flags &= ~MDP_USEDFPU;
 2661         if (i386_use_fxsave) {
 2662                 pcb->pcb_savefpu.sv_xmm.sv_env.en_cw = __OpenBSD_NPXCW__;
 2663                 pcb->pcb_savefpu.sv_xmm.sv_env.en_mxcsr = __INITIAL_MXCSR__;
 2664         } else
 2665                 pcb->pcb_savefpu.sv_87.sv_env.en_cw = __OpenBSD_NPXCW__;
 2666 
 2667         tf->tf_fs = LSEL(LUDATA_SEL, SEL_UPL);
 2668         tf->tf_gs = LSEL(LUDATA_SEL, SEL_UPL);
 2669         tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL);
 2670         tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL);
 2671         tf->tf_ebp = 0;
 2672         tf->tf_ebx = (int)PS_STRINGS;
 2673         tf->tf_eip = pack->ep_entry;
 2674         tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL);
 2675         tf->tf_eflags = PSL_USERSET;
 2676         tf->tf_esp = stack;
 2677         tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL);
 2678 
 2679         retval[1] = 0;
 2680 }
 2681 
 2682 /*
 2683  * Initialize segments and descriptor tables
 2684  */
 2685 
 2686 union descriptor ldt[NLDT];
 2687 struct gate_descriptor idt_region[NIDT];
 2688 struct gate_descriptor *idt = idt_region;
 2689 
 2690 extern  struct user *proc0paddr;
 2691 
 2692 void
 2693 setgate(struct gate_descriptor *gd, void *func, int args, int type, int dpl,
 2694     int seg)
 2695 {
 2696 
 2697         gd->gd_looffset = (int)func;
 2698         gd->gd_selector = GSEL(seg, SEL_KPL);
 2699         gd->gd_stkcpy = args;
 2700         gd->gd_xx = 0;
 2701         gd->gd_type = type;
 2702         gd->gd_dpl = dpl;
 2703         gd->gd_p = 1;
 2704         gd->gd_hioffset = (int)func >> 16;
 2705 }
 2706 
 2707 void
 2708 unsetgate(struct gate_descriptor *gd)
 2709 {
 2710         gd->gd_p = 0;
 2711         gd->gd_hioffset = 0;
 2712         gd->gd_looffset = 0;
 2713         gd->gd_selector = 0;
 2714         gd->gd_xx = 0;
 2715         gd->gd_stkcpy = 0;
 2716         gd->gd_type = 0;
 2717         gd->gd_dpl = 0;
 2718 }
 2719 
 2720 void
 2721 setregion(struct region_descriptor *rd, void *base, size_t limit)
 2722 {
 2723 
 2724         rd->rd_limit = (int)limit;
 2725         rd->rd_base = (int)base;
 2726 }
 2727 
 2728 void
 2729 setsegment(struct segment_descriptor *sd, void *base, size_t limit, int type,
 2730     int dpl, int def32, int gran)
 2731 {
 2732 
 2733         sd->sd_lolimit = (int)limit;
 2734         sd->sd_lobase = (int)base;
 2735         sd->sd_type = type;
 2736         sd->sd_dpl = dpl;
 2737         sd->sd_p = 1;
 2738         sd->sd_hilimit = (int)limit >> 16;
 2739         sd->sd_xx = 0;
 2740         sd->sd_def32 = def32;
 2741         sd->sd_gran = gran;
 2742         sd->sd_hibase = (int)base >> 24;
 2743 }
 2744 
 2745 #define IDTVEC(name)    __CONCAT(X, name)
 2746 extern int IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
 2747     IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm),
 2748     IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), IDTVEC(page),
 2749     IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), IDTVEC(syscall), IDTVEC(mchk),
 2750     IDTVEC(osyscall), IDTVEC(simd);
 2751 
 2752 #if defined(I586_CPU)
 2753 extern int IDTVEC(f00f_redirect);
 2754 
 2755 int cpu_f00f_bug = 0;
 2756 
 2757 void
 2758 fix_f00f(void)
 2759 {
 2760         struct region_descriptor region;
 2761         vaddr_t va;
 2762         void *p;
 2763         pt_entry_t *pte;
 2764 
 2765         /* Allocate two new pages */
 2766         va = uvm_km_zalloc(kernel_map, NBPG*2);
 2767         p = (void *)(va + NBPG - 7*sizeof(*idt));
 2768 
 2769         /* Copy over old IDT */
 2770         bcopy(idt, p, sizeof(idt_region));
 2771         idt = p;
 2772 
 2773         /* Fix up paging redirect */
 2774         setgate(&idt[ 14], &IDTVEC(f00f_redirect), 0, SDT_SYS386TGT, SEL_KPL,
 2775             GCODE_SEL);
 2776 
 2777         /* Map first page RO */
 2778         pte = PTE_BASE + atop(va);
 2779         *pte &= ~PG_RW;
 2780 
 2781         /* Reload idtr */
 2782         setregion(&region, idt, sizeof(idt_region) - 1);
 2783         lidt(&region);
 2784 
 2785         /* Tell the rest of the world */
 2786         cpu_f00f_bug = 1;
 2787 }
 2788 #endif
 2789 
 2790 #ifdef MULTIPROCESSOR
 2791 void
 2792 cpu_init_idt()
 2793 {
 2794         struct region_descriptor region;
 2795         setregion(&region, idt, NIDT * sizeof(idt[0]) - 1);
 2796         lidt(&region);
 2797 }
 2798 
 2799 void
 2800 cpu_default_ldt(struct cpu_info *ci)
 2801 {
 2802         ci->ci_ldt = ldt;
 2803         ci->ci_ldt_len = sizeof(ldt);
 2804 }
 2805 
 2806 void
 2807 cpu_alloc_ldt(struct cpu_info *ci)
 2808 {
 2809         union descriptor *cpu_ldt;
 2810         size_t len = sizeof(ldt);
 2811 
 2812         cpu_ldt = (union descriptor *)uvm_km_alloc(kernel_map, len);
 2813         bcopy(ldt, cpu_ldt, len);
 2814         ci->ci_ldt = cpu_ldt;
 2815         ci->ci_ldt_len = len;
 2816 }
 2817 
 2818 void
 2819 cpu_init_ldt(struct cpu_info *ci)
 2820 {
 2821         setsegment(&ci->ci_gdt[GLDT_SEL].sd, ci->ci_ldt, ci->ci_ldt_len - 1,
 2822             SDT_SYSLDT, SEL_KPL, 0, 0);
 2823 }
 2824 #endif  /* MULTIPROCESSOR */
 2825 
 2826 void
 2827 init386(paddr_t first_avail)
 2828 {
 2829         int i, kb;
 2830         struct region_descriptor region;
 2831         bios_memmap_t *im;
 2832 
 2833         proc0.p_addr = proc0paddr;
 2834         cpu_info_primary.ci_self = &cpu_info_primary;
 2835         cpu_info_primary.ci_curpcb = &proc0.p_addr->u_pcb;
 2836 
 2837         /*
 2838          * Initialize the I/O port and I/O mem extent maps.
 2839          * Note: we don't have to check the return value since
 2840          * creation of a fixed extent map will never fail (since
 2841          * descriptor storage has already been allocated).
 2842          *
 2843          * N.B. The iomem extent manages _all_ physical addresses
 2844          * on the machine.  When the amount of RAM is found, the two
 2845          * extents of RAM are allocated from the map (0 -> ISA hole
 2846          * and end of ISA hole -> end of RAM).
 2847          */
 2848         ioport_ex = extent_create("ioport", 0x0, 0xffff, M_DEVBUF,
 2849             (caddr_t)ioport_ex_storage, sizeof(ioport_ex_storage),
 2850             EX_NOCOALESCE|EX_NOWAIT);
 2851         iomem_ex = extent_create("iomem", 0x0, 0xffffffff, M_DEVBUF,
 2852             (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage),
 2853             EX_NOCOALESCE|EX_NOWAIT);
 2854 
 2855         /* make bootstrap gdt gates and memory segments */
 2856         setsegment(&gdt[GCODE_SEL].sd, 0, 0xfffff, SDT_MEMERA, SEL_KPL, 1, 1);
 2857         setsegment(&gdt[GICODE_SEL].sd, 0, 0xfffff, SDT_MEMERA, SEL_KPL, 1, 1);
 2858         setsegment(&gdt[GDATA_SEL].sd, 0, 0xfffff, SDT_MEMRWA, SEL_KPL, 1, 1);
 2859         setsegment(&gdt[GLDT_SEL].sd, ldt, sizeof(ldt) - 1, SDT_SYSLDT,
 2860             SEL_KPL, 0, 0);
 2861         setsegment(&gdt[GUCODE_SEL].sd, 0, atop(I386_MAX_EXE_ADDR) - 1,
 2862             SDT_MEMERA, SEL_UPL, 1, 1);
 2863         setsegment(&gdt[GUDATA_SEL].sd, 0, atop(VM_MAXUSER_ADDRESS) - 1,
 2864             SDT_MEMRWA, SEL_UPL, 1, 1);
 2865         setsegment(&gdt[GCPU_SEL].sd, &cpu_info_primary,
 2866             sizeof(struct cpu_info)-1, SDT_MEMRWA, SEL_KPL, 0, 0);
 2867 
 2868         /* make ldt gates and memory segments */
 2869         setgate(&ldt[LSYS5CALLS_SEL].gd, &IDTVEC(osyscall), 1, SDT_SYS386CGT,
 2870             SEL_UPL, GCODE_SEL);
 2871         ldt[LUCODE_SEL] = gdt[GUCODE_SEL];
 2872         ldt[LUDATA_SEL] = gdt[GUDATA_SEL];
 2873         ldt[LBSDICALLS_SEL] = ldt[LSYS5CALLS_SEL];
 2874 
 2875         /* exceptions */
 2876         setgate(&idt[  0], &IDTVEC(div),     0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2877         setgate(&idt[  1], &IDTVEC(dbg),     0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2878         setgate(&idt[  2], &IDTVEC(nmi),     0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2879         setgate(&idt[  3], &IDTVEC(bpt),     0, SDT_SYS386TGT, SEL_UPL, GCODE_SEL);
 2880         setgate(&idt[  4], &IDTVEC(ofl),     0, SDT_SYS386TGT, SEL_UPL, GCODE_SEL);
 2881         setgate(&idt[  5], &IDTVEC(bnd),     0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2882         setgate(&idt[  6], &IDTVEC(ill),     0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2883         setgate(&idt[  7], &IDTVEC(dna),     0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2884         setgate(&idt[  8], &IDTVEC(dble),    0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2885         setgate(&idt[  9], &IDTVEC(fpusegm), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2886         setgate(&idt[ 10], &IDTVEC(tss),     0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2887         setgate(&idt[ 11], &IDTVEC(missing), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2888         setgate(&idt[ 12], &IDTVEC(stk),     0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2889         setgate(&idt[ 13], &IDTVEC(prot),    0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2890         setgate(&idt[ 14], &IDTVEC(page),    0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2891         setgate(&idt[ 15], &IDTVEC(rsvd),    0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2892         setgate(&idt[ 16], &IDTVEC(fpu),     0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2893         setgate(&idt[ 17], &IDTVEC(align),   0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2894         setgate(&idt[ 18], &IDTVEC(mchk),    0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2895         setgate(&idt[ 19], &IDTVEC(simd),    0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2896         for (i = 20; i < NRSVIDT; i++)
 2897                 setgate(&idt[i], &IDTVEC(rsvd), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
 2898         for (i = NRSVIDT; i < NIDT; i++)
 2899                 unsetgate(&idt[i]);
 2900         setgate(&idt[128], &IDTVEC(syscall), 0, SDT_SYS386TGT, SEL_UPL, GCODE_SEL);
 2901 
 2902         setregion(&region, gdt, NGDT * sizeof(union descriptor) - 1);
 2903         lgdt(&region);
 2904         setregion(&region, idt, sizeof(idt_region) - 1);
 2905         lidt(&region);
 2906 
 2907 #if NISA > 0
 2908         isa_defaultirq();
 2909 #endif
 2910 
 2911         consinit();     /* XXX SHOULD NOT BE DONE HERE */
 2912                         /* XXX here, until we can use bios for printfs */
 2913 
 2914         /*
 2915          * Saving SSE registers won't work if the save area isn't
 2916          * 16-byte aligned.
 2917          */
 2918         if (offsetof(struct user, u_pcb.pcb_savefpu) & 0xf)
 2919                 panic("init386: pcb_savefpu not 16-byte aligned");
 2920 
 2921         /* call pmap initialization to make new kernel address space */
 2922         pmap_bootstrap((vaddr_t)atdevbase + IOM_SIZE);
 2923 
 2924         /*
 2925          * Boot arguments are in a single page specified by /boot.
 2926          *
 2927          * We require the "new" vector form, as well as memory ranges
 2928          * to be given in bytes rather than KB.
 2929          */
 2930         if ((bootapiver & (BAPIV_VECTOR | BAPIV_BMEMMAP)) ==
 2931             (BAPIV_VECTOR | BAPIV_BMEMMAP)) {
 2932                 if (bootargc > NBPG)
 2933                         panic("too many boot args");
 2934 
 2935                 if (extent_alloc_region(iomem_ex, (paddr_t)bootargv, bootargc,
 2936                     EX_NOWAIT))
 2937                         panic("cannot reserve /boot args memory");
 2938 
 2939                 pmap_enter(pmap_kernel(), (vaddr_t)bootargp, (paddr_t)bootargv,
 2940                     VM_PROT_READ|VM_PROT_WRITE,
 2941                     VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
 2942 
 2943                 bios_getopt();
 2944 
 2945         } else
 2946                 panic("/boot too old: upgrade!");
 2947 
 2948 #ifdef DIAGNOSTIC
 2949         if (bios_memmap == NULL)
 2950                 panic("no BIOS memory map supplied");
 2951 #endif
 2952  
 2953 #if defined(MULTIPROCESSOR)
 2954         /* install the page after boot args as PT page for first 4M */
 2955         pmap_enter(pmap_kernel(), (u_long)vtopte(0),
 2956            round_page((vaddr_t)(bootargv + bootargc)),
 2957                 VM_PROT_READ|VM_PROT_WRITE,
 2958                 VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
 2959         memset(vtopte(0), 0, NBPG);  /* make sure it is clean before using */
 2960 #endif
 2961 
 2962         /*
 2963          * account all the memory passed in the map from /boot
 2964          * calculate avail_end and count the physmem.
 2965          */
 2966         avail_end = 0;
 2967         physmem = 0;
 2968 #ifdef DEBUG
 2969         printf("memmap:");
 2970 #endif
 2971         for(i = 0, im = bios_memmap; im->type != BIOS_MAP_END; im++)
 2972                 if (im->type == BIOS_MAP_FREE) {
 2973                         paddr_t a, e;
 2974 #ifdef DEBUG
 2975                         printf(" %llx-%llx", im->addr, im->addr + im->size);
 2976 #endif
 2977 
 2978                         if (im->addr >= 0x100000000ULL) {
 2979 #ifdef DEBUG
 2980                                 printf("-H");
 2981 #endif
 2982                                 continue;
 2983                         }
 2984 
 2985                         a = round_page(im->addr);
 2986                         if (im->addr + im->size <= 0xfffff000ULL)
 2987                                 e = trunc_page(im->addr + im->size);
 2988                         else {
 2989 #ifdef DEBUG
 2990                                 printf("-T");
 2991 #endif
 2992                                 e = 0xfffff000;
 2993                         }
 2994 
 2995                         /* skip first eight pages */
 2996                         if (a < 8 * NBPG)
 2997                                 a = 8 * NBPG;
 2998 
 2999                         /* skip shorter than page regions */
 3000                         if (a >= e || (e - a) < NBPG) {
 3001 #ifdef DEBUG
 3002                                 printf("-S");
 3003 #endif
 3004                                 continue;
 3005                         }
 3006                         if ((a > IOM_BEGIN && a < IOM_END) ||
 3007                             (e > IOM_BEGIN && e < IOM_END)) {
 3008 #ifdef DEBUG
 3009                                 printf("-I");
 3010 #endif
 3011                                 continue;
 3012                         }
 3013 
 3014                         if (extent_alloc_region(iomem_ex, a, e - a, EX_NOWAIT))
 3015                                 /* XXX What should we do? */
 3016                                 printf("\nWARNING: CAN'T ALLOCATE RAM (%x-%x)"
 3017                                     " FROM IOMEM EXTENT MAP!\n", a, e);
 3018 
 3019                         physmem += atop(e - a);
 3020                         dumpmem[i].start = atop(a);
 3021                         dumpmem[i].end = atop(e);
 3022                         i++;
 3023                         avail_end = max(avail_end, e);
 3024                 }
 3025 
 3026         ndumpmem = i;
 3027         avail_end -= round_page(MSGBUFSIZE);
 3028 
 3029 #ifdef DEBUG
 3030         printf(": %lx\n", avail_end);
 3031 #endif
 3032         if (physmem < atop(4 * 1024 * 1024)) {
 3033                 printf("\awarning: too little memory available;"
 3034                     "running in degraded mode\npress a key to confirm\n\n");
 3035                 cngetc();
 3036         }
 3037 
 3038 #ifdef DEBUG
 3039         printf("physload: ");
 3040 #endif
 3041         kb = atop(KERNTEXTOFF - KERNBASE);
 3042         if (kb > atop(0x100000)) {
 3043                 paddr_t lim = atop(0x100000);
 3044 #ifdef DEBUG
 3045                 printf(" %x-%x (<16M)", lim, kb);
 3046 #endif
 3047                 uvm_page_physload(lim, kb, lim, kb, VM_FREELIST_FIRST16);
 3048         }
 3049 
 3050         for (i = 0; i < ndumpmem; i++) {
 3051                 paddr_t a, e;
 3052                 paddr_t lim;
 3053 
 3054                 a = dumpmem[i].start;
 3055                 e = dumpmem[i].end;
 3056                 if (a < atop(first_avail) && e > atop(first_avail))
 3057                         a = atop(first_avail);
 3058                 if (e > atop(avail_end))
 3059                         e = atop(avail_end);
 3060 
 3061                 if (a < e) {
 3062                         if (a < atop(16 * 1024 * 1024)) {
 3063                                 lim = MIN(atop(16 * 1024 * 1024), e);
 3064 #ifdef DEBUG
 3065 -                               printf(" %x-%x (<16M)", a, lim);
 3066 #endif
 3067                                 uvm_page_physload(a, lim, a, lim,
 3068                                     VM_FREELIST_FIRST16);
 3069                                 if (e > lim) {
 3070 #ifdef DEBUG
 3071 -                                       printf(" %x-%x", lim, e);
 3072 #endif
 3073                                         uvm_page_physload(lim, e, lim, e,
 3074                                             VM_FREELIST_DEFAULT);
 3075                                 }
 3076                         } else {
 3077 #ifdef DEBUG
 3078 -                               printf(" %x-%x", a, e);
 3079 #endif
 3080                                 uvm_page_physload(a, e, a, e,
 3081                                     VM_FREELIST_DEFAULT);
 3082                         }
 3083                 }
 3084         }
 3085 #ifdef DEBUG
 3086         printf("\n");
 3087 #endif
 3088         tlbflush();
 3089 #if 0
 3090 #if NISADMA > 0
 3091         /*
 3092          * Some motherboards/BIOSes remap the 384K of RAM that would
 3093          * normally be covered by the ISA hole to the end of memory
 3094          * so that it can be used.  However, on a 16M system, this
 3095          * would cause bounce buffers to be allocated and used.
 3096          * This is not desirable behaviour, as more than 384K of
 3097          * bounce buffers might be allocated.  As a work-around,
 3098          * we round memory down to the nearest 1M boundary if
 3099          * we're using any isadma devices and the remapped memory
 3100          * is what puts us over 16M.
 3101          */
 3102         if (extmem > (15*1024) && extmem < (16*1024)) {
 3103                 printf("Warning: ignoring %dk of remapped memory\n",
 3104                     extmem - (15*1024));
 3105                 extmem = (15*1024);
 3106         }
 3107 #endif
 3108 #endif
 3109 
 3110 #ifdef DDB
 3111         db_machine_init();
 3112         ddb_init();
 3113         if (boothowto & RB_KDB)
 3114                 Debugger();
 3115 #endif
 3116 #ifdef KGDB
 3117         kgdb_port_init();
 3118         if (boothowto & RB_KDB) {
 3119                 kgdb_debug_init = 1;
 3120                 kgdb_connect(1);
 3121         }
 3122 #endif /* KGDB */
 3123 }
 3124 
 3125 /*
 3126  * cpu_exec_aout_makecmds():
 3127  *      cpu-dependent a.out format hook for execve().
 3128  *
 3129  * Determine of the given exec package refers to something which we
 3130  * understand and, if so, set up the vmcmds for it.
 3131  */
 3132 int
 3133 cpu_exec_aout_makecmds(struct proc *p, struct exec_package *epp)
 3134 {
 3135         return ENOEXEC;
 3136 }
 3137 
 3138 /*
 3139  * consinit:
 3140  * initialize the system console.
 3141  * XXX - shouldn't deal with this initted thing, but then,
 3142  * it shouldn't be called from init386 either.
 3143  */
 3144 void
 3145 consinit()
 3146 {
 3147         static int initted;
 3148 
 3149         if (initted)
 3150                 return;
 3151         initted = 1;
 3152         cninit();
 3153 }
 3154 
 3155 #ifdef KGDB
 3156 void
 3157 kgdb_port_init()
 3158 {
 3159 
 3160 #if (NCOM > 0 || NPCCOM > 0)
 3161         if (!strcmp(kgdb_devname, "com") || !strcmp(kgdb_devname, "pccom")) {
 3162                 bus_space_tag_t tag = I386_BUS_SPACE_IO;
 3163                 com_kgdb_attach(tag, comkgdbaddr, comkgdbrate, COM_FREQ,
 3164                     comkgdbmode);
 3165         }
 3166 #endif
 3167 }
 3168 #endif /* KGDB */
 3169 
 3170 void
 3171 cpu_reset()
 3172 {
 3173         struct region_descriptor region;
 3174 
 3175         disable_intr();
 3176 
 3177         if (cpuresetfn)
 3178                 (*cpuresetfn)();
 3179 
 3180         /*
 3181          * The keyboard controller has 4 random output pins, one of which is
 3182          * connected to the RESET pin on the CPU in many PCs.  We tell the
 3183          * keyboard controller to pulse this line a couple of times.
 3184          */
 3185         outb(IO_KBD + KBCMDP, KBC_PULSE0);
 3186         delay(100000);
 3187         outb(IO_KBD + KBCMDP, KBC_PULSE0);
 3188         delay(100000);
 3189 
 3190         /*
 3191          * Try to cause a triple fault and watchdog reset by setting the
 3192          * IDT to point to nothing.
 3193          */
 3194         bzero((caddr_t)idt, sizeof(idt_region));
 3195         setregion(&region, idt, sizeof(idt_region) - 1);
 3196         lidt(&region);
 3197         __asm __volatile("divl %0,%1" : : "q" (0), "a" (0));
 3198 
 3199 #if 1
 3200         /*
 3201          * Try to cause a triple fault and watchdog reset by unmapping the
 3202          * entire address space.
 3203          */
 3204         bzero((caddr_t)PTD, NBPG);
 3205         tlbflush();
 3206 #endif
 3207 
 3208         for (;;);
 3209 }
 3210 
 3211 void
 3212 cpu_initclocks(void)
 3213 {
 3214         (*initclock_func)();
 3215 
 3216         if (initclock_func == i8254_initclocks)
 3217                 i8254_inittimecounter();
 3218         else
 3219                 i8254_inittimecounter_simple();
 3220 }
 3221 
 3222 void
 3223 need_resched(struct cpu_info *ci)
 3224 {
 3225         struct proc *p;
 3226 
 3227         ci->ci_want_resched = 1;
 3228 
 3229         /*
 3230          * Need to catch the curproc in case it's cleared just
 3231          * between the check and the aston().
 3232          */
 3233         if ((p = ci->ci_curproc) != NULL)
 3234                 aston(p);
 3235 }
 3236 
 3237 #ifdef MULTIPROCESSOR
 3238 /* Allocate an IDT vector slot within the given range.
 3239  * XXX needs locking to avoid MP allocation races.
 3240  */
 3241 
 3242 int
 3243 idt_vec_alloc(int low, int high)
 3244 {
 3245         int vec;
 3246 
 3247         for (vec = low; vec <= high; vec++)
 3248                 if (idt[vec].gd_p == 0)
 3249                         return (vec);
 3250         return (0);
 3251 }
 3252 
 3253 void
 3254 idt_vec_set(int vec, void (*function)(void))
 3255 {
 3256         setgate(&idt[vec], function, 0, SDT_SYS386IGT, SEL_KPL, GCODE_SEL);
 3257 }
 3258 
 3259 void
 3260 idt_vec_free(int vec)
 3261 {
 3262         unsetgate(&idt[vec]);
 3263 }
 3264 #endif  /* MULTIPROCESSOR */
 3265 
 3266 /*
 3267  * machine dependent system variables.
 3268  */
 3269 int
 3270 cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
 3271     size_t newlen, struct proc *p)
 3272 {
 3273         dev_t dev;
 3274 
 3275         switch (name[0]) {
 3276         case CPU_CONSDEV:
 3277                 if (namelen != 1)
 3278                         return (ENOTDIR);               /* overloaded */
 3279 
 3280                 if (cn_tab != NULL)
 3281                         dev = cn_tab->cn_dev;
 3282                 else
 3283                         dev = NODEV;
 3284                 return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev));
 3285 #if NBIOS > 0
 3286         case CPU_BIOS:
 3287                 return bios_sysctl(name + 1, namelen - 1, oldp, oldlenp,
 3288                     newp, newlen, p);
 3289 #endif
 3290         case CPU_BLK2CHR:
 3291                 if (namelen != 2)
 3292                         return (ENOTDIR);               /* overloaded */
 3293                 dev = blktochr((dev_t)name[1]);
 3294                 return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev));
 3295         case CPU_CHR2BLK:
 3296                 if (namelen != 2)
 3297                         return (ENOTDIR);               /* overloaded */
 3298                 dev = chrtoblk((dev_t)name[1]);
 3299                 return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev));
 3300         case CPU_ALLOWAPERTURE:
 3301 #ifdef APERTURE
 3302                 if (securelevel > 0)
 3303                         return (sysctl_int_lower(oldp, oldlenp, newp, newlen,
 3304                             &allowaperture));
 3305                 else
 3306                         return (sysctl_int(oldp, oldlenp, newp, newlen,
 3307                             &allowaperture));
 3308 #else
 3309                 return (sysctl_rdint(oldp, oldlenp, newp, 0));
 3310 #endif
 3311         case CPU_CPUVENDOR:
 3312                 return (sysctl_rdstring(oldp, oldlenp, newp, cpu_vendor));
 3313         case CPU_CPUID:
 3314                 return (sysctl_rdint(oldp, oldlenp, newp, cpu_id));
 3315         case CPU_CPUFEATURE:
 3316                 return (sysctl_rdint(oldp, oldlenp, newp, curcpu()->ci_feature_flags));
 3317 #if NAPM > 0
 3318         case CPU_APMWARN:
 3319                 return (sysctl_int(oldp, oldlenp, newp, newlen, &cpu_apmwarn));
 3320         case CPU_APMHALT:
 3321                 return (sysctl_int(oldp, oldlenp, newp, newlen, &cpu_apmhalt));
 3322 #endif
 3323         case CPU_KBDRESET:
 3324                 if (securelevel > 0)
 3325                         return (sysctl_rdint(oldp, oldlenp, newp,
 3326                             kbd_reset));
 3327                 else
 3328                         return (sysctl_int(oldp, oldlenp, newp, newlen,
 3329                             &kbd_reset));
 3330 #ifdef USER_LDT
 3331         case CPU_USERLDT:
 3332                 return (sysctl_int(oldp, oldlenp, newp, newlen,
 3333                     &user_ldt_enable));
 3334 #endif
 3335         case CPU_OSFXSR:
 3336                 return (sysctl_rdint(oldp, oldlenp, newp, i386_use_fxsave));
 3337         case CPU_SSE:
 3338                 return (sysctl_rdint(oldp, oldlenp, newp, i386_has_sse));
 3339         case CPU_SSE2:
 3340                 return (sysctl_rdint(oldp, oldlenp, newp, i386_has_sse2));
 3341         case CPU_XCRYPT:
 3342                 return (sysctl_rdint(oldp, oldlenp, newp, i386_has_xcrypt));
 3343         default:
 3344                 return (EOPNOTSUPP);
 3345         }
 3346         /* NOTREACHED */
 3347 }
 3348 
 3349 int
 3350 bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int cacheable,
 3351     bus_space_handle_t *bshp)
 3352 {
 3353         int error;
 3354         struct extent *ex;
 3355 
 3356         /*
 3357          * Pick the appropriate extent map.
 3358          */
 3359         switch (t) {
 3360         case I386_BUS_SPACE_IO:
 3361                 ex = ioport_ex;
 3362                 break;
 3363 
 3364         case I386_BUS_SPACE_MEM:
 3365                 ex = iomem_ex;
 3366                 break;
 3367 
 3368         default:
 3369                 panic("bus_space_map: bad bus space tag");
 3370         }
 3371 
 3372         /*
 3373          * Before we go any further, let's make sure that this
 3374          * region is available.
 3375          */
 3376         error = extent_alloc_region(ex, bpa, size,
 3377             EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0));
 3378         if (error)
 3379                 return (error);
 3380 
 3381         /*
 3382          * For I/O space, that's all she wrote.
 3383          */
 3384         if (t == I386_BUS_SPACE_IO) {
 3385                 *bshp = bpa;
 3386                 return (0);
 3387         }
 3388 
 3389         if (IOM_BEGIN <= bpa && bpa <= IOM_END) {
 3390                 *bshp = (bus_space_handle_t)ISA_HOLE_VADDR(bpa);
 3391                 return (0);
 3392         }
 3393 
 3394         /*
 3395          * For memory space, map the bus physical address to
 3396          * a kernel virtual address.
 3397          */
 3398         error = bus_mem_add_mapping(bpa, size, cacheable, bshp);
 3399         if (error) {
 3400                 if (extent_free(ex, bpa, size, EX_NOWAIT |
 3401                     (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
 3402                         printf("bus_space_map: pa 0x%lx, size 0x%lx\n",
 3403                             bpa, size);
 3404                         printf("bus_space_map: can't free region\n");
 3405                 }
 3406         }
 3407 
 3408         return (error);
 3409 }
 3410 
 3411 int
 3412 _bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
 3413     int cacheable, bus_space_handle_t *bshp)
 3414 {
 3415         /*
 3416          * For I/O space, that's all she wrote.
 3417          */
 3418         if (t == I386_BUS_SPACE_IO) {
 3419                 *bshp = bpa;
 3420                 return (0);
 3421         }
 3422 
 3423         /*
 3424          * For memory space, map the bus physical address to
 3425          * a kernel virtual address.
 3426          */
 3427         return (bus_mem_add_mapping(bpa, size, cacheable, bshp));
 3428 }
 3429 
 3430 int
 3431 bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend,
 3432     bus_size_t size, bus_size_t alignment, bus_size_t boundary,
 3433     int cacheable, bus_addr_t *bpap, bus_space_handle_t *bshp)
 3434 {
 3435         struct extent *ex;
 3436         u_long bpa;
 3437         int error;
 3438 
 3439         /*
 3440          * Pick the appropriate extent map.
 3441          */
 3442         switch (t) {
 3443         case I386_BUS_SPACE_IO:
 3444                 ex = ioport_ex;
 3445                 break;
 3446 
 3447         case I386_BUS_SPACE_MEM:
 3448                 ex = iomem_ex;
 3449                 break;
 3450 
 3451         default:
 3452                 panic("bus_space_alloc: bad bus space tag");
 3453         }
 3454 
 3455         /*
 3456          * Sanity check the allocation against the extent's boundaries.
 3457          */
 3458         if (rstart < ex->ex_start || rend > ex->ex_end)
 3459                 panic("bus_space_alloc: bad region start/end");
 3460 
 3461         /*
 3462          * Do the requested allocation.
 3463          */
 3464         error = extent_alloc_subregion(ex, rstart, rend, size, alignment, 0,
 3465             boundary, EX_NOWAIT | (ioport_malloc_safe ?  EX_MALLOCOK : 0),
 3466             &bpa);
 3467 
 3468         if (error)
 3469                 return (error);
 3470 
 3471         /*
 3472          * For I/O space, that's all she wrote.
 3473          */
 3474         if (t == I386_BUS_SPACE_IO) {
 3475                 *bshp = *bpap = bpa;
 3476                 return (0);
 3477         }
 3478 
 3479         /*
 3480          * For memory space, map the bus physical address to
 3481          * a kernel virtual address.
 3482          */
 3483         error = bus_mem_add_mapping(bpa, size, cacheable, bshp);
 3484         if (error) {
 3485                 if (extent_free(iomem_ex, bpa, size, EX_NOWAIT |
 3486                     (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
 3487                         printf("bus_space_alloc: pa 0x%lx, size 0x%lx\n",
 3488                             bpa, size);
 3489                         printf("bus_space_alloc: can't free region\n");
 3490                 }
 3491         }
 3492 
 3493         *bpap = bpa;
 3494 
 3495         return (error);
 3496 }
 3497 
 3498 int
 3499 bus_mem_add_mapping(bus_addr_t bpa, bus_size_t size, int cacheable,
 3500     bus_space_handle_t *bshp)
 3501 {
 3502         u_long pa, endpa;
 3503         vaddr_t va;
 3504         pt_entry_t *pte;
 3505         bus_size_t map_size;
 3506 
 3507         pa = trunc_page(bpa);
 3508         endpa = round_page(bpa + size);
 3509 
 3510 #ifdef DIAGNOSTIC
 3511         if (endpa <= pa && endpa != 0)
 3512                 panic("bus_mem_add_mapping: overflow");
 3513 #endif
 3514 
 3515         map_size = endpa - pa;
 3516 
 3517         va = uvm_km_valloc(kernel_map, map_size);
 3518         if (va == 0)
 3519                 return (ENOMEM);
 3520 
 3521         *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
 3522 
 3523         for (; map_size > 0;
 3524             pa += PAGE_SIZE, va += PAGE_SIZE, map_size -= PAGE_SIZE) {
 3525                 pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
 3526 
 3527                 pte = kvtopte(va);
 3528                 if (cacheable)
 3529                         *pte &= ~PG_N;
 3530                 else
 3531                         *pte |= PG_N;
 3532                 pmap_tlb_shootpage(pmap_kernel(), va);
 3533         }
 3534 
 3535         pmap_tlb_shootwait();
 3536         pmap_update(pmap_kernel());
 3537 
 3538         return 0;
 3539 }
 3540 
 3541 void
 3542 bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
 3543 {
 3544         struct extent *ex;
 3545         u_long va, endva;
 3546         bus_addr_t bpa;
 3547 
 3548         /*
 3549          * Find the correct extent and bus physical address.
 3550          */
 3551         if (t == I386_BUS_SPACE_IO) {
 3552                 ex = ioport_ex;
 3553                 bpa = bsh;
 3554         } else if (t == I386_BUS_SPACE_MEM) {
 3555                 ex = iomem_ex;
 3556                 bpa = (bus_addr_t)ISA_PHYSADDR(bsh);
 3557                 if (IOM_BEGIN <= bpa && bpa <= IOM_END)
 3558                         goto ok;
 3559 
 3560                 va = trunc_page(bsh);
 3561                 endva = round_page(bsh + size);
 3562 
 3563 #ifdef DIAGNOSTIC
 3564                 if (endva <= va)
 3565                         panic("bus_space_unmap: overflow");
 3566 #endif
 3567 
 3568                 (void) pmap_extract(pmap_kernel(), va, &bpa);
 3569                 bpa += (bsh & PGOFSET);
 3570 
 3571                 /*
 3572                  * Free the kernel virtual mapping.
 3573                  */
 3574                 uvm_km_free(kernel_map, va, endva - va);
 3575         } else
 3576                 panic("bus_space_unmap: bad bus space tag");
 3577 
 3578 ok:
 3579         if (extent_free(ex, bpa, size,
 3580             EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
 3581                 printf("bus_space_unmap: %s 0x%lx, size 0x%lx\n",
 3582                     (t == I386_BUS_SPACE_IO) ? "port" : "pa", bpa, size);
 3583                 printf("bus_space_unmap: can't free region\n");
 3584         }
 3585 }
 3586 
 3587 void
 3588 _bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size,
 3589     bus_addr_t *adrp)
 3590 {
 3591         u_long va, endva;
 3592         bus_addr_t bpa;
 3593 
 3594         /*
 3595          * Find the correct bus physical address.
 3596          */
 3597         if (t == I386_BUS_SPACE_IO) {
 3598                 bpa = bsh;
 3599         } else if (t == I386_BUS_SPACE_MEM) {
 3600                 bpa = (bus_addr_t)ISA_PHYSADDR(bsh);
 3601                 if (IOM_BEGIN <= bpa && bpa <= IOM_END)
 3602                         goto ok;
 3603 
 3604                 va = trunc_page(bsh);
 3605                 endva = round_page(bsh + size);
 3606 
 3607 #ifdef DIAGNOSTIC
 3608                 if (endva <= va)
 3609                         panic("_bus_space_unmap: overflow");
 3610 #endif
 3611 
 3612                 (void) pmap_extract(pmap_kernel(), va, &bpa);
 3613                 bpa += (bsh & PGOFSET);
 3614 
 3615                 /*
 3616                  * Free the kernel virtual mapping.
 3617                  */
 3618                 uvm_km_free(kernel_map, va, endva - va);
 3619         } else
 3620                 panic("bus_space_unmap: bad bus space tag");
 3621 
 3622 ok:
 3623         if (adrp != NULL)
 3624                 *adrp = bpa;
 3625 }
 3626 
 3627 void
 3628 bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
 3629 {
 3630 
 3631         /* bus_space_unmap() does all that we need to do. */
 3632         bus_space_unmap(t, bsh, size);
 3633 }
 3634 
 3635 int
 3636 bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
 3637     bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
 3638 {
 3639         *nbshp = bsh + offset;
 3640         return (0);
 3641 }
 3642 
 3643 /*
 3644  * Common function for DMA map creation.  May be called by bus-specific
 3645  * DMA map creation functions.
 3646  */
 3647 int
 3648 _bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments,
 3649     bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
 3650 {
 3651         struct i386_bus_dmamap *map;
 3652         void *mapstore;
 3653         size_t mapsize;
 3654 
 3655         /*
 3656          * Allocate and initialize the DMA map.  The end of the map
 3657          * is a variable-sized array of segments, so we allocate enough
 3658          * room for them in one shot.
 3659          *
 3660          * Note we don't preserve the WAITOK or NOWAIT flags.  Preservation
 3661          * of ALLOCNOW notifies others that we've reserved these resources,
 3662          * and they are not to be freed.
 3663          *
 3664          * The bus_dmamap_t includes one bus_dma_segment_t, hence
 3665          * the (nsegments - 1).
 3666          */
 3667         mapsize = sizeof(struct i386_bus_dmamap) +
 3668             (sizeof(bus_dma_segment_t) * (nsegments - 1));
 3669         if ((mapstore = malloc(mapsize, M_DEVBUF,
 3670             (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL)
 3671                 return (ENOMEM);
 3672 
 3673         bzero(mapstore, mapsize);
 3674         map = (struct i386_bus_dmamap *)mapstore;
 3675         map->_dm_size = size;
 3676         map->_dm_segcnt = nsegments;
 3677         map->_dm_maxsegsz = maxsegsz;
 3678         map->_dm_boundary = boundary;
 3679         map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
 3680         map->dm_mapsize = 0;            /* no valid mappings */
 3681         map->dm_nsegs = 0;
 3682 
 3683         *dmamp = map;
 3684         return (0);
 3685 }
 3686 
 3687 /*
 3688  * Common function for DMA map destruction.  May be called by bus-specific
 3689  * DMA map destruction functions.
 3690  */
 3691 void
 3692 _bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map)
 3693 {
 3694 
 3695         free(map, M_DEVBUF);
 3696 }
 3697 
 3698 /*
 3699  * Common function for loading a DMA map with a linear buffer.  May
 3700  * be called by bus-specific DMA map load functions.
 3701  */
 3702 int
 3703 _bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
 3704     bus_size_t buflen, struct proc *p, int flags)
 3705 {
 3706         bus_addr_t lastaddr;
 3707         int seg, error;
 3708 
 3709         /*
 3710          * Make sure that on error condition we return "no valid mappings".
 3711          */
 3712         map->dm_mapsize = 0;
 3713         map->dm_nsegs = 0;
 3714 
 3715         if (buflen > map->_dm_size)
 3716                 return (EINVAL);
 3717 
 3718         seg = 0;
 3719         error = _bus_dmamap_load_buffer(t, map, buf, buflen, p, flags,
 3720             &lastaddr, &seg, 1);
 3721         if (error == 0) {
 3722                 map->dm_mapsize = buflen;
 3723                 map->dm_nsegs = seg + 1;
 3724         }
 3725         return (error);
 3726 }
 3727 
 3728 /*
 3729  * Like _bus_dmamap_load(), but for mbufs.
 3730  */
 3731 int
 3732 _bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m0,
 3733     int flags)
 3734 {
 3735         paddr_t lastaddr;
 3736         int seg, error, first;
 3737         struct mbuf *m;
 3738 
 3739         /*
 3740          * Make sure that on error condition we return "no valid mappings".
 3741          */
 3742         map->dm_mapsize = 0;
 3743         map->dm_nsegs = 0;
 3744 
 3745 #ifdef DIAGNOSTIC
 3746         if ((m0->m_flags & M_PKTHDR) == 0)
 3747                 panic("_bus_dmamap_load_mbuf: no packet header");
 3748 #endif
 3749 
 3750         if (m0->m_pkthdr.len > map->_dm_size)
 3751                 return (EINVAL);
 3752 
 3753         first = 1;
 3754         seg = 0;
 3755         error = 0;
 3756         for (m = m0; m != NULL && error == 0; m = m->m_next) {
 3757                 if (m->m_len == 0)
 3758                         continue;
 3759                 error = _bus_dmamap_load_buffer(t, map, m->m_data, m->m_len,
 3760                     NULL, flags, &lastaddr, &seg, first);
 3761                 first = 0;
 3762         }
 3763         if (error == 0) {
 3764                 map->dm_mapsize = m0->m_pkthdr.len;
 3765                 map->dm_nsegs = seg + 1;
 3766         }
 3767         return (error);
 3768 }
 3769 
 3770 /*
 3771  * Like _bus_dmamap_load(), but for uios.
 3772  */
 3773 int
 3774 _bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio,
 3775     int flags)
 3776 {
 3777         paddr_t lastaddr;
 3778         int seg, i, error, first;
 3779         bus_size_t minlen, resid;
 3780         struct proc *p = NULL;
 3781         struct iovec *iov;
 3782         caddr_t addr;
 3783 
 3784         /*
 3785          * Make sure that on error condition we return "no valid mappings".
 3786          */
 3787         map->dm_mapsize = 0;
 3788         map->dm_nsegs = 0;
 3789 
 3790         resid = uio->uio_resid;
 3791         iov = uio->uio_iov;
 3792 
 3793         if (resid > map->_dm_size)
 3794                 return (EINVAL);
 3795 
 3796         if (uio->uio_segflg == UIO_USERSPACE) {
 3797                 p = uio->uio_procp;
 3798 #ifdef DIAGNOSTIC
 3799                 if (p == NULL)
 3800                         panic("_bus_dmamap_load_uio: USERSPACE but no proc");
 3801 #endif
 3802         }
 3803 
 3804         first = 1;
 3805         seg = 0;
 3806         error = 0;
 3807         for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) {
 3808                 /*
 3809                  * Now at the first iovec to load.  Load each iovec
 3810                  * until we have exhausted the residual count.
 3811                  */
 3812                 minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len;
 3813                 addr = (caddr_t)iov[i].iov_base;
 3814 
 3815                 error = _bus_dmamap_load_buffer(t, map, addr, minlen,
 3816                     p, flags, &lastaddr, &seg, first);
 3817                 first = 0;
 3818 
 3819                 resid -= minlen;
 3820         }
 3821         if (error == 0) {
 3822                 map->dm_mapsize = uio->uio_resid;
 3823                 map->dm_nsegs = seg + 1;
 3824         }
 3825         return (error);
 3826 }
 3827 
 3828 /*
 3829  * Like _bus_dmamap_load(), but for raw memory allocated with
 3830  * bus_dmamem_alloc().
 3831  */
 3832 int
 3833 _bus_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map, bus_dma_segment_t *segs,
 3834     int nsegs, bus_size_t size, int flags)
 3835 {
 3836         if (nsegs > map->_dm_segcnt || size > map->_dm_size)
 3837                 return (EINVAL);
 3838 
 3839         /*
 3840          * Make sure we don't cross any boundaries.
 3841          */
 3842         if (map->_dm_boundary) {
 3843                 bus_addr_t bmask = ~(map->_dm_boundary - 1);
 3844                 int i;
 3845 
 3846                 for (i = 0; i < nsegs; i++) {
 3847                         if (segs[i].ds_len > map->_dm_maxsegsz)
 3848                                 return (EINVAL);
 3849                         if ((segs[i].ds_addr & bmask) !=
 3850                             ((segs[i].ds_addr + segs[i].ds_len - 1) & bmask))
 3851                                 return (EINVAL);
 3852                 }
 3853         }
 3854 
 3855         bcopy(segs, map->dm_segs, nsegs * sizeof(*segs));
 3856         map->dm_nsegs = nsegs;
 3857         return (0);
 3858 }
 3859 
 3860 /*
 3861  * Common function for unloading a DMA map.  May be called by
 3862  * bus-specific DMA map unload functions.
 3863  */
 3864 void
 3865 _bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map)
 3866 {
 3867 
 3868         /*
 3869          * No resources to free; just mark the mappings as
 3870          * invalid.
 3871          */
 3872         map->dm_mapsize = 0;
 3873         map->dm_nsegs = 0;
 3874 }
 3875 
 3876 /*
 3877  * Common function for DMA-safe memory allocation.  May be called
 3878  * by bus-specific DMA memory allocation functions.
 3879  */
 3880 int
 3881 _bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
 3882     bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
 3883     int flags)
 3884 {
 3885 
 3886         return (_bus_dmamem_alloc_range(t, size, alignment, boundary,
 3887             segs, nsegs, rsegs, flags, 0, trunc_page(avail_end)));
 3888 }
 3889 
 3890 /*
 3891  * Common function for freeing DMA-safe memory.  May be called by
 3892  * bus-specific DMA memory free functions.
 3893  */
 3894 void
 3895 _bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs)
 3896 {
 3897         struct vm_page *m;
 3898         bus_addr_t addr;
 3899         struct pglist mlist;
 3900         int curseg;
 3901 
 3902         /*
 3903          * Build a list of pages to free back to the VM system.
 3904          */
 3905         TAILQ_INIT(&mlist);
 3906         for (curseg = 0; curseg < nsegs; curseg++) {
 3907                 for (addr = segs[curseg].ds_addr;
 3908                     addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
 3909                     addr += PAGE_SIZE) {
 3910                         m = PHYS_TO_VM_PAGE(addr);
 3911                         TAILQ_INSERT_TAIL(&mlist, m, pageq);
 3912                 }
 3913         }
 3914 
 3915         uvm_pglistfree(&mlist);
 3916 }
 3917 
 3918 /*
 3919  * Common function for mapping DMA-safe memory.  May be called by
 3920  * bus-specific DMA memory map functions.
 3921  */
 3922 int
 3923 _bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
 3924     size_t size, caddr_t *kvap, int flags)
 3925 {
 3926         vaddr_t va;
 3927         bus_addr_t addr;
 3928         int curseg;
 3929 
 3930         size = round_page(size);
 3931         va = uvm_km_valloc(kernel_map, size);
 3932         if (va == 0)
 3933                 return (ENOMEM);
 3934 
 3935         *kvap = (caddr_t)va;
 3936 
 3937         for (curseg = 0; curseg < nsegs; curseg++) {
 3938                 for (addr = segs[curseg].ds_addr;
 3939                     addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
 3940                     addr += PAGE_SIZE, va += PAGE_SIZE, size -= PAGE_SIZE) {
 3941                         if (size == 0)
 3942                                 panic("_bus_dmamem_map: size botch");
 3943                         pmap_enter(pmap_kernel(), va, addr,
 3944                             VM_PROT_READ | VM_PROT_WRITE,
 3945                             VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED);
 3946                 }
 3947         }
 3948         pmap_update(pmap_kernel());
 3949 
 3950         return (0);
 3951 }
 3952 
 3953 /*
 3954  * Common function for unmapping DMA-safe memory.  May be called by
 3955  * bus-specific DMA memory unmapping functions.
 3956  */
 3957 void
 3958 _bus_dmamem_unmap(bus_dma_tag_t t, caddr_t kva, size_t size)
 3959 {
 3960 
 3961 #ifdef DIAGNOSTIC
 3962         if ((u_long)kva & PGOFSET)
 3963                 panic("_bus_dmamem_unmap");
 3964 #endif
 3965 
 3966         size = round_page(size);
 3967         uvm_km_free(kernel_map, (vaddr_t)kva, size);
 3968 }
 3969 
 3970 /*
 3971  * Common functin for mmap(2)'ing DMA-safe memory.  May be called by
 3972  * bus-specific DMA mmap(2)'ing functions.
 3973  */
 3974 paddr_t
 3975 _bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, off_t off,
 3976     int prot, int flags)
 3977 {
 3978         int i;
 3979 
 3980         for (i = 0; i < nsegs; i++) {
 3981 #ifdef DIAGNOSTIC
 3982                 if (off & PGOFSET)
 3983                         panic("_bus_dmamem_mmap: offset unaligned");
 3984                 if (segs[i].ds_addr & PGOFSET)
 3985                         panic("_bus_dmamem_mmap: segment unaligned");
 3986                 if (segs[i].ds_len & PGOFSET)
 3987                         panic("_bus_dmamem_mmap: segment size not multiple"
 3988                             " of page size");
 3989 #endif
 3990                 if (off >= segs[i].ds_len) {
 3991                         off -= segs[i].ds_len;
 3992                         continue;
 3993                 }
 3994 
 3995                 return (atop(segs[i].ds_addr + off));
 3996         }
 3997 
 3998         /* Page not found. */
 3999         return (-1);
 4000 }
 4001 
 4002 /**********************************************************************
 4003  * DMA utility functions
 4004  **********************************************************************/
 4005 /*
 4006  * Utility function to load a linear buffer.  lastaddrp holds state
 4007  * between invocations (for multiple-buffer loads).  segp contains
 4008  * the starting segment on entrance, and the ending segment on exit.
 4009  * first indicates if this is the first invocation of this function.
 4010  */
 4011 int
 4012 _bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
 4013     bus_size_t buflen, struct proc *p, int flags, paddr_t *lastaddrp, int *segp,
 4014     int first)
 4015 {
 4016         bus_size_t sgsize;
 4017         bus_addr_t curaddr, lastaddr, baddr, bmask;
 4018         vaddr_t vaddr = (vaddr_t)buf;
 4019         int seg;
 4020         pmap_t pmap;
 4021 
 4022         if (p != NULL)
 4023                 pmap = p->p_vmspace->vm_map.pmap;
 4024         else
 4025                 pmap = pmap_kernel();
 4026 
 4027         lastaddr = *lastaddrp;
 4028         bmask  = ~(map->_dm_boundary - 1);
 4029 
 4030         for (seg = *segp; buflen > 0 ; ) {
 4031                 /*
 4032                  * Get the physical address for this segment.
 4033                  */
 4034                 pmap_extract(pmap, vaddr, (paddr_t *)&curaddr);
 4035 
 4036                 /*
 4037                  * Compute the segment size, and adjust counts.
 4038                  */
 4039                 sgsize = PAGE_SIZE - ((u_long)vaddr & PGOFSET);
 4040                 if (buflen < sgsize)
 4041                         sgsize = buflen;
 4042 
 4043                 /*
 4044                  * Make sure we don't cross any boundaries.
 4045                  */
 4046                 if (map->_dm_boundary > 0) {
 4047                         baddr = (curaddr + map->_dm_boundary) & bmask;
 4048                         if (sgsize > (baddr - curaddr))
 4049                                 sgsize = (baddr - curaddr);
 4050                 }
 4051 
 4052                 /*
 4053                  * Insert chunk into a segment, coalescing with
 4054                  * previous segment if possible.
 4055                  */
 4056                 if (first) {
 4057                         map->dm_segs[seg].ds_addr = curaddr;
 4058                         map->dm_segs[seg].ds_len = sgsize;
 4059                         first = 0;
 4060                 } else {
 4061                         if (curaddr == lastaddr &&
 4062                             (map->dm_segs[seg].ds_len + sgsize) <=
 4063                              map->_dm_maxsegsz &&
 4064                             (map->_dm_boundary == 0 ||
 4065                              (map->dm_segs[seg].ds_addr & bmask) ==
 4066                              (curaddr & bmask)))
 4067                                 map->dm_segs[seg].ds_len += sgsize;
 4068                         else {
 4069                                 if (++seg >= map->_dm_segcnt)
 4070                                         break;
 4071                                 map->dm_segs[seg].ds_addr = curaddr;
 4072                                 map->dm_segs[seg].ds_len = sgsize;
 4073                         }
 4074                 }
 4075 
 4076                 lastaddr = curaddr + sgsize;
 4077                 vaddr += sgsize;
 4078                 buflen -= sgsize;
 4079         }
 4080 
 4081         *segp = seg;
 4082         *lastaddrp = lastaddr;
 4083 
 4084         /*
 4085          * Did we fit?
 4086          */
 4087         if (buflen != 0)
 4088                 return (EFBIG);         /* XXX better return value here? */
 4089         return (0);
 4090 }
 4091 
 4092 /*
 4093  * Allocate physical memory from the given physical address range.
 4094  * Called by DMA-safe memory allocation methods.
 4095  */
 4096 int
 4097 _bus_dmamem_alloc_range(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
 4098     bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
 4099     int flags, paddr_t low, paddr_t high)
 4100 {
 4101         paddr_t curaddr, lastaddr;
 4102         struct vm_page *m;
 4103         struct pglist mlist;
 4104         int curseg, error;
 4105 
 4106         /* Always round the size. */
 4107         size = round_page(size);
 4108 
 4109         TAILQ_INIT(&mlist);
 4110         /*
 4111          * Allocate pages from the VM system.
 4112          * For non-ISA mappings first try higher memory segments.
 4113          */
 4114         if (high <= ISA_DMA_BOUNCE_THRESHOLD || (error = uvm_pglistalloc(size,
 4115             round_page(ISA_DMA_BOUNCE_THRESHOLD), high, alignment, boundary,
 4116             &mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0)))
 4117                 error = uvm_pglistalloc(size, low, high, alignment, boundary,
 4118                     &mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0);
 4119         if (error)
 4120                 return (error);
 4121 
 4122         /*
 4123          * Compute the location, size, and number of segments actually
 4124          * returned by the VM code.
 4125          */
 4126         m = TAILQ_FIRST(&mlist);
 4127         curseg = 0;
 4128         lastaddr = segs[curseg].ds_addr = VM_PAGE_TO_PHYS(m);
 4129         segs[curseg].ds_len = PAGE_SIZE;
 4130 
 4131         for (m = TAILQ_NEXT(m, pageq); m != NULL; m = TAILQ_NEXT(m, pageq)) {
 4132                 curaddr = VM_PAGE_TO_PHYS(m);
 4133 #ifdef DIAGNOSTIC
 4134                 if (curseg == nsegs) {
 4135                         printf("uvm_pglistalloc returned too many\n");
 4136                         panic("_bus_dmamem_alloc_range");
 4137                 }
 4138                 if (curaddr < low || curaddr >= high) {
 4139                         printf("uvm_pglistalloc returned non-sensical"
 4140                             " address 0x%lx\n", curaddr);
 4141                         panic("_bus_dmamem_alloc_range");
 4142                 }
 4143 #endif
 4144                 if (curaddr == (lastaddr + PAGE_SIZE))
 4145                         segs[curseg].ds_len += PAGE_SIZE;
 4146                 else {
 4147                         curseg++;
 4148                         segs[curseg].ds_addr = curaddr;
 4149                         segs[curseg].ds_len = PAGE_SIZE;
 4150                 }
 4151                 lastaddr = curaddr;
 4152         }
 4153         *rsegs = curseg + 1;
 4154 
 4155         return (0);
 4156 }
 4157 
 4158 #ifdef DIAGNOSTIC
 4159 void
 4160 splassert_check(int wantipl, const char *func)
 4161 {
 4162         if (lapic_tpr < wantipl)
 4163                 splassert_fail(wantipl, lapic_tpr, func);
 4164         if (wantipl == IPL_NONE && curcpu()->ci_idepth != 0)
 4165                 splassert_fail(-1, curcpu()->ci_idepth, func);
 4166 }
 4167 #endif
 4168 
 4169 #ifdef MULTIPROCESSOR
 4170 void
 4171 i386_intlock(int ipl)
 4172 {
 4173         if (ipl < IPL_SCHED)
 4174                 __mp_lock(&kernel_lock);
 4175 
 4176         curcpu()->ci_idepth++;
 4177 }
 4178 
 4179 void
 4180 i386_intunlock(int ipl)
 4181 {
 4182         curcpu()->ci_idepth--;
 4183 
 4184         if (ipl < IPL_SCHED)
 4185                 __mp_unlock(&kernel_lock);
 4186 }
 4187 
 4188 void
 4189 i386_softintlock(void)
 4190 {
 4191         __mp_lock(&kernel_lock);
 4192         curcpu()->ci_idepth++;
 4193 }
 4194 
 4195 void
 4196 i386_softintunlock(void)
 4197 {
 4198         curcpu()->ci_idepth--;
 4199         __mp_unlock(&kernel_lock);
 4200 }
 4201 #endif
 4202 
 4203 /*
 4204  * Software interrupt registration
 4205  *
 4206  * We hand-code this to ensure that it's atomic.
 4207  */
 4208 void
 4209 softintr(int sir, int vec)
 4210 {
 4211         __asm __volatile("orl %1, %0" : "=m" (ipending) : "ir" (sir));
 4212 #ifdef MULTIPROCESSOR
 4213         i82489_writereg(LAPIC_ICRLO,
 4214             vec | LAPIC_DLMODE_FIXED | LAPIC_LVL_ASSERT | LAPIC_DEST_SELF);
 4215 #endif
 4216 }
 4217 
 4218 /*
 4219  * Raise current interrupt priority level, and return the old one.
 4220  */
 4221 int
 4222 splraise(int ncpl)
 4223 {
 4224         int ocpl;
 4225 
 4226         _SPLRAISE(ocpl, ncpl);
 4227         return (ocpl);
 4228 }
 4229 
 4230 /*
 4231  * Restore an old interrupt priority level.  If any thereby unmasked
 4232  * interrupts are pending, call Xspllower() to process them.
 4233  */
 4234 void
 4235 splx(int ncpl)
 4236 {
 4237         _SPLX(ncpl);
 4238 }
 4239 
 4240 /*
 4241  * Same as splx(), but we return the old value of spl, for the
 4242  * benefit of some splsoftclock() callers.
 4243  */
 4244 int
 4245 spllower(int ncpl)
 4246 {
 4247         int ocpl = lapic_tpr;
 4248 
 4249         splx(ncpl);
 4250         return (ocpl);
 4251 }

/* [<][>][^][v][top][bottom][index][help] */