[BACK]Return to machdep.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / i386 / i386

Annotation of src/sys/arch/i386/i386/machdep.c, Revision 1.649

1.649   ! ad          1: /*     $NetBSD: machdep.c,v 1.648 2008/11/12 01:14:01 cegger Exp $     */
1.231     thorpej     2:
                      3: /*-
1.621     tls         4:  * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008 The NetBSD Foundation, Inc.
1.231     thorpej     5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
1.571     jmmv        8:  * by Charles M. Hannum, by Jason R. Thorpe of the Numerical Aerospace
                      9:  * Simulation Facility, NASA Ames Research Center and by Julio M. Merino Vidal.
1.231     thorpej    10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     21:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     22:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     23:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     24:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     25:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     26:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     27:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     28:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     29:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     30:  * POSSIBILITY OF SUCH DAMAGE.
                     31:  */
1.125     cgd        32:
1.1       cgd        33: /*-
                     34:  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
                     35:  * All rights reserved.
                     36:  *
                     37:  * This code is derived from software contributed to Berkeley by
                     38:  * William Jolitz.
                     39:  *
                     40:  * Redistribution and use in source and binary forms, with or without
                     41:  * modification, are permitted provided that the following conditions
                     42:  * are met:
                     43:  * 1. Redistributions of source code must retain the above copyright
                     44:  *    notice, this list of conditions and the following disclaimer.
                     45:  * 2. Redistributions in binary form must reproduce the above copyright
                     46:  *    notice, this list of conditions and the following disclaimer in the
                     47:  *    documentation and/or other materials provided with the distribution.
1.528     agc        48:  * 3. Neither the name of the University nor the names of its contributors
1.1       cgd        49:  *    may be used to endorse or promote products derived from this software
                     50:  *    without specific prior written permission.
                     51:  *
                     52:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     53:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     54:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     55:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     56:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     57:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     58:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     59:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     60:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     61:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     62:  * SUCH DAMAGE.
                     63:  *
1.125     cgd        64:  *     @(#)machdep.c   7.4 (Berkeley) 6/3/91
1.1       cgd        65:  */
1.460     lukem      66:
                     67: #include <sys/cdefs.h>
1.649   ! ad         68: __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.648 2008/11/12 01:14:01 cegger Exp $");
1.271     thorpej    69:
1.538     christos   70: #include "opt_beep.h"
                     71: #include "opt_compat_ibcs2.h"
                     72: #include "opt_compat_mach.h"   /* need to get the right segment def */
                     73: #include "opt_compat_netbsd.h"
                     74: #include "opt_compat_svr4.h"
                     75: #include "opt_cpureset_delay.h"
1.309     jonathan   76: #include "opt_ddb.h"
1.377     ws         77: #include "opt_ipkdb.h"
1.443     lukem      78: #include "opt_kgdb.h"
1.455     fvdl       79: #include "opt_mtrr.h"
1.523     martin     80: #include "opt_multiprocessor.h"
1.619     joerg      81: #include "opt_physmem.h"
1.538     christos   82: #include "opt_realmem.h"
                     83: #include "opt_user_ldt.h"
                     84: #include "opt_vm86.h"
1.587     jmcneill   85: #include "opt_xbox.h"
1.622     bouyer     86: #include "opt_xen.h"
                     87: #include "isa.h"
                     88: #include "pci.h"
                     89:
1.1       cgd        90:
1.59      mycroft    91: #include <sys/param.h>
                     92: #include <sys/systm.h>
1.508     thorpej    93: #include <sys/signal.h>
1.59      mycroft    94: #include <sys/signalvar.h>
                     95: #include <sys/kernel.h>
1.603     yamt       96: #include <sys/cpu.h>
1.59      mycroft    97: #include <sys/user.h>
                     98: #include <sys/exec.h>
                     99: #include <sys/reboot.h>
                    100: #include <sys/conf.h>
                    101: #include <sys/malloc.h>
                    102: #include <sys/mbuf.h>
                    103: #include <sys/msgbuf.h>
                    104: #include <sys/mount.h>
1.204     thorpej   105: #include <sys/extent.h>
1.123     cgd       106: #include <sys/syscallargs.h>
1.291     thorpej   107: #include <sys/core.h>
                    108: #include <sys/kcore.h>
1.508     thorpej   109: #include <sys/ucontext.h>
1.519     nathanw   110: #include <sys/ras.h>
1.643     wrstuden  111: #include <sys/sa.h>
                    112: #include <sys/savar.h>
1.522     ragge     113: #include <sys/ksyms.h>
1.645     dyoung    114: #include <sys/device.h>
1.57      cgd       115:
1.377     ws        116: #ifdef IPKDB
                    117: #include <ipkdb/ipkdb.h>
                    118: #endif
                    119:
1.235     thorpej   120: #ifdef KGDB
                    121: #include <sys/kgdb.h>
                    122: #endif
                    123:
1.104     cgd       124: #include <dev/cons.h>
1.390     mrg       125:
                    126: #include <uvm/uvm_extern.h>
1.393     fvdl      127: #include <uvm/uvm_page.h>
1.284     mrg       128:
1.200     christos  129: #include <sys/sysctl.h>
                    130:
1.602     xtraeme   131: #include <x86/cpu_msr.h>
                    132:
1.59      mycroft   133: #include <machine/cpu.h>
                    134: #include <machine/cpufunc.h>
1.484     fvdl      135: #include <machine/cpuvar.h>
1.178     mycroft   136: #include <machine/gdt.h>
1.603     yamt      137: #include <machine/intr.h>
1.574     kardel    138: #include <machine/kcore.h>
1.149     mycroft   139: #include <machine/pio.h>
1.59      mycroft   140: #include <machine/psl.h>
                    141: #include <machine/reg.h>
                    142: #include <machine/specialreg.h>
1.255     drochner  143: #include <machine/bootinfo.h>
1.455     fvdl      144: #include <machine/mtrr.h>
1.574     kardel    145: #include <x86/x86/tsc.h>
                    146:
1.570     jmmv      147: #include <machine/multiboot.h>
1.622     bouyer    148: #ifdef XEN
                    149: #include <xen/evtchn.h>
                    150: #include <xen/xen.h>
                    151: #include <xen/hypervisor.h>
                    152:
                    153: /* #define     XENDEBUG */
                    154: /* #define     XENDEBUG_LOW */
                    155:
                    156: #ifdef XENDEBUG
                    157: #define        XENPRINTF(x) printf x
                    158: #define        XENPRINTK(x) printk x
                    159: #else
                    160: #define        XENPRINTF(x)
                    161: #define        XENPRINTK(x)
                    162: #endif
                    163: #define        PRINTK(x) printf x
                    164: #endif /* XEN */
1.43      brezak    165:
1.146     cgd       166: #include <dev/isa/isareg.h>
1.372     drochner  167: #include <machine/isa_machdep.h>
1.164     cgd       168: #include <dev/ic/i8042reg.h>
1.43      brezak    169:
1.200     christos  170: #ifdef DDB
                    171: #include <machine/db_machdep.h>
                    172: #include <ddb/db_extern.h>
                    173: #endif
                    174:
1.184     mycroft   175: #ifdef VM86
                    176: #include <machine/vm86.h>
                    177: #endif
                    178:
1.587     jmcneill  179: #ifdef XBOX
                    180: #include <machine/xbox.h>
                    181:
                    182: int arch_i386_is_xbox = 0;
                    183: uint32_t arch_i386_xbox_memsize = 0;
                    184: #endif
                    185:
1.473     tshiozak  186: #include "acpi.h"
1.576     christos  187: #include "apmbios.h"
1.258     jtk       188: #include "bioscall.h"
1.207     jtk       189:
1.259     jtk       190: #if NBIOSCALL > 0
                    191: #include <machine/bioscall.h>
                    192: #endif
                    193:
1.473     tshiozak  194: #if NACPI > 0
                    195: #include <dev/acpi/acpivar.h>
                    196: #define ACPI_MACHDEP_PRIVATE
                    197: #include <machine/acpi_machdep.h>
                    198: #endif
                    199:
1.576     christos  200: #if NAPMBIOS > 0
1.207     jtk       201: #include <machine/apmvar.h>
1.258     jtk       202: #endif
                    203:
1.59      mycroft   204: #include "isa.h"
1.231     thorpej   205: #include "isadma.h"
1.59      mycroft   206: #include "npx.h"
1.522     ragge     207: #include "ksyms.h"
1.2       cgd       208:
1.593     gdt       209: #include "cardbus.h"
                    210: #if NCARDBUS > 0
                    211: /* For rbus_min_start hint. */
                    212: #include <machine/bus.h>
                    213: #include <dev/cardbus/rbus.h>
                    214: #include <machine/rbus_machdep.h>
                    215: #endif
                    216:
1.384     jdolecek  217: #include "mca.h"
                    218: #if NMCA > 0
                    219: #include <machine/mca_machdep.h>       /* for mca_busprobe() */
                    220: #endif
                    221:
1.484     fvdl      222: #ifdef MULTIPROCESSOR          /* XXX */
                    223: #include <machine/mpbiosvar.h> /* XXX */
                    224: #endif                         /* XXX */
                    225:
1.104     cgd       226: /* the following is used externally (sysctl_hw) */
1.549     wiz       227: char machine[] = "i386";               /* CPU "architecture" */
1.232     veego     228: char machine_arch[] = "i386";          /* machine == machine_arch */
1.104     cgd       229:
1.559     thorpej   230: extern struct bi_devmatch *x86_alldisks;
                    231: extern int x86_ndisks;
1.342     fvdl      232:
1.328     bouyer    233: #ifdef CPURESET_DELAY
                    234: int    cpureset_delay = CPURESET_DELAY;
                    235: #else
                    236: int     cpureset_delay = 2000; /* default to 2s */
                    237: #endif
                    238:
1.455     fvdl      239: #ifdef MTRR
1.513     fvdl      240: struct mtrr_funcs *mtrr_funcs;
1.455     fvdl      241: #endif
                    242:
1.515     fvdl      243: #ifdef COMPAT_NOMID
1.566     christos  244: static int exec_nomid(struct lwp *, struct exec_package *);
1.550     junyoung  245: #endif
1.515     fvdl      246:
1.59      mycroft   247: int    physmem;
1.621     tls       248:
1.524     drochner  249: unsigned int cpu_feature;
1.553     lukem     250: unsigned int cpu_feature2;
1.596     daniel    251: unsigned int cpu_feature_padlock;
1.59      mycroft   252: int    cpu_class;
1.428     fvdl      253: int    i386_fpu_present;
                    254: int    i386_fpu_exception;
                    255: int    i386_fpu_fdivbug;
1.59      mycroft   256:
1.451     thorpej   257: int    i386_use_fxsave;
                    258: int    i386_has_sse;
                    259: int    i386_has_sse2;
1.450     thorpej   260:
1.314     thorpej   261: vaddr_t        msgbuf_vaddr;
1.589     pavel     262: struct {
                    263:        paddr_t paddr;
                    264:        psize_t sz;
                    265: } msgbuf_p_seg[VM_PHYSSEG_MAX];
                    266: unsigned int msgbuf_p_cnt = 0;
1.314     thorpej   267:
                    268: vaddr_t        idt_vaddr;
                    269: paddr_t        idt_paddr;
                    270: vaddr_t        pentium_idt_vaddr;
1.59      mycroft   271:
1.444     chs       272: struct vm_map *mb_map = NULL;
                    273: struct vm_map *phys_map = NULL;
1.48      brezak    274:
1.314     thorpej   275: extern paddr_t avail_start, avail_end;
1.622     bouyer    276: #ifdef XEN
                    277: extern paddr_t pmap_pa_start, pmap_pa_end;
                    278: void hypervisor_callback(void);
                    279: void failsafe_callback(void);
                    280: #endif
1.1       cgd       281:
1.622     bouyer    282: #ifdef XEN
                    283: void (*delay_func)(unsigned int) = xen_delay;
                    284: void (*initclock_func)(void) = xen_initclocks;
                    285: #else
1.611     joerg     286: void (*delay_func)(unsigned int) = i8254_delay;
1.542     junyoung  287: void (*initclock_func)(void) = i8254_initclocks;
1.622     bouyer    288: #endif
                    289:
1.484     fvdl      290:
1.204     thorpej   291: /*
1.291     thorpej   292:  * Size of memory segments, before any memory is stolen.
                    293:  */
                    294: phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
                    295: int    mem_cluster_cnt;
                    296:
1.542     junyoung  297: void   init386(paddr_t);
                    298: void   initgdt(union descriptor *);
1.255     drochner  299:
1.568     perry     300: void   add_mem_cluster(uint64_t, uint64_t, uint32_t);
1.433     kanaoka   301:
1.521     dsl       302: extern int time_adjusted;
1.484     fvdl      303:
1.571     jmmv      304: int *esym;
1.633     ad        305: int *eblob;
1.571     jmmv      306: extern int boothowto;
                    307:
1.622     bouyer    308: #ifndef XEN
                    309:
1.571     jmmv      310: /* Base memory reported by BIOS. */
                    311: #ifndef REALBASEMEM
                    312: int    biosbasemem = 0;
                    313: #else
                    314: int    biosbasemem = REALBASEMEM;
                    315: #endif
                    316:
                    317: /* Extended memory reported by BIOS. */
                    318: #ifndef REALEXTMEM
                    319: int    biosextmem = 0;
                    320: #else
                    321: int    biosextmem = REALEXTMEM;
                    322: #endif
                    323:
1.577     mrg       324: /* Set if any boot-loader set biosbasemem/biosextmem. */
                    325: int    biosmem_implicit;
                    326:
1.571     jmmv      327: /* Representation of the bootinfo structure constructed by a NetBSD native
                    328:  * boot loader.  Only be used by native_loader(). */
                    329: struct bootinfo_source {
                    330:        uint32_t bs_naddrs;
                    331:        paddr_t bs_addrs[1]; /* Actually longer. */
                    332: };
                    333:
                    334: /* Only called by locore.h; no need to be in a header file. */
                    335: void   native_loader(int, int, struct bootinfo_source *, paddr_t, int, int);
                    336:
                    337: /*
                    338:  * Called as one of the very first things during system startup (just after
                    339:  * the boot loader gave control to the kernel image), this routine is in
                    340:  * charge of retrieving the parameters passed in by the boot loader and
                    341:  * storing them in the appropriate kernel variables.
                    342:  *
                    343:  * WARNING: Because the kernel has not yet relocated itself to KERNBASE,
                    344:  * special care has to be taken when accessing memory because absolute
                    345:  * addresses (referring to kernel symbols) do not work.  So:
                    346:  *
                    347:  *     1) Avoid jumps to absolute addresses (such as gotos and switches).
                    348:  *     2) To access global variables use their physical address, which
                    349:  *        can be obtained using the RELOC macro.
                    350:  */
                    351: void
1.586     christos  352: native_loader(int bl_boothowto, int bl_bootdev,
1.571     jmmv      353:     struct bootinfo_source *bl_bootinfo, paddr_t bl_esym,
1.572     jmmv      354:     int bl_biosextmem, int bl_biosbasemem)
1.571     jmmv      355: {
                    356: #define RELOC(type, x) ((type)((vaddr_t)(x) - KERNBASE))
                    357:
                    358:        *RELOC(int *, &boothowto) = bl_boothowto;
                    359:
                    360: #ifdef COMPAT_OLDBOOT
                    361:        /*
                    362:         * Pre-1.3 boot loaders gave the boot device as a parameter
                    363:         * (instead of a bootinfo entry).
                    364:         */
                    365:        *RELOC(int *, &bootdev) = bl_bootdev;
                    366: #endif
                    367:
                    368:        /*
                    369:         * The boot loader provides a physical, non-relocated address
                    370:         * for the symbols table's end.  We need to convert it to a
                    371:         * virtual address.
                    372:         */
                    373:        if (bl_esym != 0)
                    374:                *RELOC(int **, &esym) = (int *)((vaddr_t)bl_esym + KERNBASE);
                    375:        else
                    376:                *RELOC(int **, &esym) = 0;
                    377:
                    378:        /*
                    379:         * Copy bootinfo entries (if any) from the boot loader's
                    380:         * representation to the kernel's bootinfo space.
                    381:         */
                    382:        if (bl_bootinfo != NULL) {
                    383:                size_t i;
                    384:                uint8_t *data;
                    385:                struct bootinfo *bidest;
1.633     ad        386:                struct btinfo_modulelist *bi;
1.571     jmmv      387:
                    388:                bidest = RELOC(struct bootinfo *, &bootinfo);
                    389:
                    390:                data = &bidest->bi_data[0];
                    391:
                    392:                for (i = 0; i < bl_bootinfo->bs_naddrs; i++) {
                    393:                        struct btinfo_common *bc;
                    394:
                    395:                        bc = (struct btinfo_common *)(bl_bootinfo->bs_addrs[i]);
                    396:
                    397:                        if ((paddr_t)(data + bc->len) >
                    398:                            (paddr_t)(&bidest->bi_data[0] + BOOTINFO_MAXSIZE))
                    399:                                break;
                    400:
                    401:                        memcpy(data, bc, bc->len);
1.633     ad        402:                        /*
                    403:                         * If any modules were loaded, record where they
                    404:                         * end.  We'll need to skip over them.
                    405:                         */
                    406:                        bi = (struct btinfo_modulelist *)data;
                    407:                        if (bi->common.type == BTINFO_MODULELIST) {
                    408:                                *RELOC(int **, &eblob) =
                    409:                                    (int *)(bi->endpa + KERNBASE);
                    410:                        }
1.571     jmmv      411:                        data += bc->len;
                    412:                }
                    413:                bidest->bi_nentries = i;
                    414:        }
                    415:
                    416:        /*
                    417:         * Configure biosbasemem and biosextmem only if they were not
                    418:         * explicitly given during the kernel's build.
                    419:         */
1.577     mrg       420:        if (*RELOC(int *, &biosbasemem) == 0) {
1.571     jmmv      421:                *RELOC(int *, &biosbasemem) = bl_biosbasemem;
1.577     mrg       422:                *RELOC(int *, &biosmem_implicit) = 1;
                    423:        }
                    424:        if (*RELOC(int *, &biosextmem) == 0) {
1.571     jmmv      425:                *RELOC(int *, &biosextmem) = bl_biosextmem;
1.577     mrg       426:                *RELOC(int *, &biosmem_implicit) = 1;
                    427:        }
1.571     jmmv      428: #undef RELOC
                    429: }
                    430:
1.622     bouyer    431: #endif /* XEN */
                    432:
1.59      mycroft   433: /*
                    434:  * Machine-dependent startup code
                    435:  */
1.32      andrew    436: void
1.1       cgd       437: cpu_startup()
                    438: {
1.589     pavel     439:        int x, y;
1.314     thorpej   440:        vaddr_t minaddr, maxaddr;
1.589     pavel     441:        psize_t sz;
1.354     lukem     442:        char pbuf[9];
1.1       cgd       443:
1.284     mrg       444:        /*
1.588     jmcneill  445:         * For console drivers that require uvm and pmap to be initialized,
                    446:         * we'll give them one more chance here...
                    447:         */
                    448:        consinit();
                    449:
1.592     jmcneill  450: #ifdef XBOX
                    451:        xbox_startup();
                    452: #endif
                    453:
1.588     jmcneill  454:        /*
1.284     mrg       455:         * Initialize error message buffer (et end of core).
                    456:         */
1.589     pavel     457:        if (msgbuf_p_cnt == 0)
                    458:                panic("msgbuf paddr map has not been set up");
                    459:        for (x = 0, sz = 0; x < msgbuf_p_cnt; sz += msgbuf_p_seg[x++].sz)
                    460:                continue;
                    461:        msgbuf_vaddr = uvm_km_alloc(kernel_map, sz, 0, UVM_KMF_VAONLY);
1.385     thorpej   462:        if (msgbuf_vaddr == 0)
1.284     mrg       463:                panic("failed to valloc msgbuf_vaddr");
1.359     thorpej   464:
1.284     mrg       465:        /* msgbuf_paddr was init'd in pmap */
1.589     pavel     466:        for (y = 0, sz = 0; y < msgbuf_p_cnt; y++) {
                    467:                for (x = 0; x < btoc(msgbuf_p_seg[y].sz); x++, sz += PAGE_SIZE)
                    468:                        pmap_kenter_pa((vaddr_t)msgbuf_vaddr + sz,
                    469:                            msgbuf_p_seg[y].paddr + x * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE);
                    470:        }
1.456     chris     471:        pmap_update(pmap_kernel());
1.359     thorpej   472:
1.600     christos  473:        initmsgbuf((void *)msgbuf_vaddr, sz);
1.284     mrg       474:
1.562     lukem     475:        printf("%s%s", copyright, version);
1.484     fvdl      476:
1.570     jmmv      477: #ifdef MULTIBOOT
                    478:        multiboot_print_info();
                    479: #endif
                    480:
1.484     fvdl      481: #ifdef TRAPLOG
                    482:        /*
                    483:         * Enable recording of branch from/to in MSR's
                    484:         */
                    485:        wrmsr(MSR_DEBUGCTLMSR, 0x1);
                    486: #endif
                    487:
1.382     mycroft   488:        format_bytes(pbuf, sizeof(pbuf), ptoa(physmem));
1.354     lukem     489:        printf("total memory = %s\n", pbuf);
1.1       cgd       490:
1.593     gdt       491: #if NCARDBUS > 0
                    492:        /* Tell RBUS how much RAM we have, so it can use heuristics. */
                    493:        rbus_min_start_hint(ptoa(physmem));
                    494: #endif
                    495:
1.547     pk        496:        minaddr = 0;
1.41      cgd       497:
1.1       cgd       498:        /*
                    499:         * Allocate a submap for physio
                    500:         */
1.284     mrg       501:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
1.601     thorpej   502:                                   VM_PHYS_SIZE, 0, false, NULL);
1.1       cgd       503:
                    504:        /*
1.229     thorpej   505:         * Finally, allocate mbuf cluster submap.
1.1       cgd       506:         */
1.334     thorpej   507:        mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
1.601     thorpej   508:            nmbclusters * mclbytes, VM_MAP_INTRSAFE, false, NULL);
1.1       cgd       509:
1.547     pk        510:        format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
1.354     lukem     511:        printf("avail memory = %s\n", pbuf);
1.1       cgd       512:
1.375     drochner  513:        /* Safe for i/o port / memory space allocation to use malloc now. */
1.622     bouyer    514: #if !defined(XEN) || defined(DOM0OPS)
1.514     fvdl      515:        x86_bus_space_mallocok();
1.622     bouyer    516: #endif
1.602     xtraeme   517:
1.603     yamt      518:        gdt_init();
                    519:        i386_proc0_tss_ldt_init();
                    520:
1.622     bouyer    521: #ifndef XEN
1.620     yamt      522:        cpu_init_tss(&cpu_info_primary);
                    523:        ltr(cpu_info_primary.ci_tss_sel);
1.622     bouyer    524: #endif
1.620     yamt      525:
1.602     xtraeme   526:        x86_init();
1.349     thorpej   527: }
                    528:
                    529: /*
                    530:  * Set up proc0's TSS and LDT.
                    531:  */
                    532: void
                    533: i386_proc0_tss_ldt_init()
                    534: {
1.603     yamt      535:        struct lwp *l;
1.349     thorpej   536:        struct pcb *pcb;
1.268     thorpej   537:
1.603     yamt      538:        l = &lwp0;
                    539:        pcb = &l->l_addr->u_pcb;
1.326     thorpej   540:
1.394     thorpej   541:        pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL);
1.646     ad        542:        pcb->pcb_cr0 = rcr0() & ~CR0_TS;
1.620     yamt      543:        pcb->pcb_esp0 = USER_TO_UAREA(l->l_addr) + KSTACK_SIZE - 16;
1.622     bouyer    544:        pcb->pcb_iopl = SEL_KPL;
1.620     yamt      545:        l->l_md.md_regs = (struct trapframe *)pcb->pcb_esp0 - 1;
1.613     ad        546:        memcpy(pcb->pcb_fsd, &gdt[GUDATA_SEL], sizeof(pcb->pcb_fsd));
                    547:        memcpy(pcb->pcb_gsd, &gdt[GUDATA_SEL], sizeof(pcb->pcb_gsd));
1.326     thorpej   548:
1.622     bouyer    549: #ifndef XEN
1.326     thorpej   550:        lldt(pcb->pcb_ldt_sel);
1.622     bouyer    551: #else
                    552:        HYPERVISOR_fpu_taskswitch();
                    553:        XENPRINTF(("lwp tss sp %p ss %04x/%04x\n",
                    554:            (void *)pcb->pcb_esp0,
                    555:            GSEL(GDATA_SEL, SEL_KPL),
                    556:            IDXSEL(GSEL(GDATA_SEL, SEL_KPL))));
                    557:        HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL), pcb->pcb_esp0);
                    558: #endif
1.484     fvdl      559: }
                    560:
1.622     bouyer    561: #ifdef XEN
                    562: /*
                    563:  * Switch context:
                    564:  * - honor CR0_TS in saved CR0 and request DNA exception on FPU use
                    565:  * - switch stack pointer for user->kernel transition
                    566:  */
                    567: void
                    568: i386_switch_context(lwp_t *l)
                    569: {
                    570:        struct cpu_info *ci;
                    571:        struct pcb *pcb = &l->l_addr->u_pcb;
                    572:
                    573:        ci = curcpu();
                    574:        if (ci->ci_fpused) {
                    575:                HYPERVISOR_fpu_taskswitch();
                    576:                ci->ci_fpused = 0;
                    577:        }
                    578:
                    579:        HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL), pcb->pcb_esp0);
                    580:
1.644     cegger    581:        if (xendomain_is_privileged()) {
1.622     bouyer    582:                int iopl = pcb->pcb_iopl;
                    583: #ifdef XEN3
                    584:                struct physdev_op physop;
                    585:                physop.cmd = PHYSDEVOP_SET_IOPL;
                    586:                physop.u.set_iopl.iopl = iopl;
                    587:                HYPERVISOR_physdev_op(&physop);
                    588: #else
                    589:                dom0_op_t op;
                    590:                op.cmd = DOM0_IOPL;
                    591:                op.u.iopl.domain = DOMID_SELF;
                    592:                op.u.iopl.iopl = iopl;
                    593:                HYPERVISOR_dom0_op(&op);
                    594: #endif
                    595:        }
                    596: }
                    597: #endif /* XEN */
                    598:
                    599: #ifndef XEN
1.484     fvdl      600: /*
1.620     yamt      601:  * Set up TSS and I/O bitmap.
                    602:  */
                    603: void
                    604: cpu_init_tss(struct cpu_info *ci)
                    605: {
                    606:        struct i386tss *tss = &ci->ci_tss;
                    607:
                    608:        tss->tss_iobase = IOMAP_INVALOFF << 16;
                    609:        tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
                    610:        tss->tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
                    611:        tss->tss_cr3 = rcr3();
                    612:        ci->ci_tss_sel = tss_alloc(tss);
                    613: }
1.622     bouyer    614: #endif /* XEN */
1.620     yamt      615:
                    616: /*
1.545     atatat    617:  * sysctl helper routine for machdep.booted_kernel
                    618:  */
                    619: static int
                    620: sysctl_machdep_booted_kernel(SYSCTLFN_ARGS)
                    621: {
                    622:        struct btinfo_bootpath *bibp;
                    623:        struct sysctlnode node;
                    624:
                    625:        bibp = lookup_bootinfo(BTINFO_BOOTPATH);
                    626:        if(!bibp)
                    627:                return(ENOENT); /* ??? */
                    628:
                    629:        node = *rnode;
                    630:        node.sysctl_data = bibp->bootpath;
                    631:        node.sysctl_size = sizeof(bibp->bootpath);
                    632:        return (sysctl_lookup(SYSCTLFN_CALL(&node)));
                    633: }
                    634:
                    635: /*
                    636:  * sysctl helper routine for machdep.diskinfo
                    637:  */
                    638: static int
                    639: sysctl_machdep_diskinfo(SYSCTLFN_ARGS)
                    640: {
                    641:        struct sysctlnode node;
                    642:
                    643:        node = *rnode;
1.559     thorpej   644:        if (x86_alldisks == NULL)
1.557     dbj       645:                return(EOPNOTSUPP);
1.559     thorpej   646:        node.sysctl_data = x86_alldisks;
1.545     atatat    647:        node.sysctl_size = sizeof(struct disklist) +
1.559     thorpej   648:            (x86_ndisks - 1) * sizeof(struct nativedisk_info);
1.557     dbj       649:        return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1.545     atatat    650: }
                    651:
                    652: /*
                    653:  * machine dependent system variables.
                    654:  */
                    655: SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
                    656: {
1.634     ad        657:        extern uint64_t tsc_freq;
1.545     atatat    658:
1.552     atatat    659:        sysctl_createv(clog, 0, NULL, NULL,
                    660:                       CTLFLAG_PERMANENT,
1.545     atatat    661:                       CTLTYPE_NODE, "machdep", NULL,
                    662:                       NULL, 0, NULL, 0,
                    663:                       CTL_MACHDEP, CTL_EOL);
                    664:
1.552     atatat    665:        sysctl_createv(clog, 0, NULL, NULL,
                    666:                       CTLFLAG_PERMANENT,
1.545     atatat    667:                       CTLTYPE_STRUCT, "console_device", NULL,
                    668:                       sysctl_consdev, 0, NULL, sizeof(dev_t),
                    669:                       CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
1.622     bouyer    670: #ifndef XEN
1.552     atatat    671:        sysctl_createv(clog, 0, NULL, NULL,
                    672:                       CTLFLAG_PERMANENT,
1.545     atatat    673:                       CTLTYPE_INT, "biosbasemem", NULL,
                    674:                       NULL, 0, &biosbasemem, 0,
                    675:                       CTL_MACHDEP, CPU_BIOSBASEMEM, CTL_EOL);
1.552     atatat    676:        sysctl_createv(clog, 0, NULL, NULL,
                    677:                       CTLFLAG_PERMANENT,
1.545     atatat    678:                       CTLTYPE_INT, "biosextmem", NULL,
                    679:                       NULL, 0, &biosextmem, 0,
                    680:                       CTL_MACHDEP, CPU_BIOSEXTMEM, CTL_EOL);
1.622     bouyer    681: #endif /* XEN */
1.552     atatat    682:        sysctl_createv(clog, 0, NULL, NULL,
                    683:                       CTLFLAG_PERMANENT,
1.545     atatat    684:                       CTLTYPE_STRING, "booted_kernel", NULL,
                    685:                       sysctl_machdep_booted_kernel, 0, NULL, 0,
                    686:                       CTL_MACHDEP, CPU_BOOTED_KERNEL, CTL_EOL);
1.552     atatat    687:        sysctl_createv(clog, 0, NULL, NULL,
                    688:                       CTLFLAG_PERMANENT,
1.545     atatat    689:                       CTLTYPE_STRUCT, "diskinfo", NULL,
                    690:                       sysctl_machdep_diskinfo, 0, NULL, 0,
                    691:                       CTL_MACHDEP, CPU_DISKINFO, CTL_EOL);
1.552     atatat    692:        sysctl_createv(clog, 0, NULL, NULL,
                    693:                       CTLFLAG_PERMANENT,
1.545     atatat    694:                       CTLTYPE_INT, "fpu_present", NULL,
                    695:                       NULL, 0, &i386_fpu_present, 0,
                    696:                       CTL_MACHDEP, CPU_FPU_PRESENT, CTL_EOL);
1.552     atatat    697:        sysctl_createv(clog, 0, NULL, NULL,
                    698:                       CTLFLAG_PERMANENT,
1.545     atatat    699:                       CTLTYPE_INT, "osfxsr", NULL,
                    700:                       NULL, 0, &i386_use_fxsave, 0,
                    701:                       CTL_MACHDEP, CPU_OSFXSR, CTL_EOL);
1.552     atatat    702:        sysctl_createv(clog, 0, NULL, NULL,
                    703:                       CTLFLAG_PERMANENT,
1.545     atatat    704:                       CTLTYPE_INT, "sse", NULL,
                    705:                       NULL, 0, &i386_has_sse, 0,
                    706:                       CTL_MACHDEP, CPU_SSE, CTL_EOL);
1.552     atatat    707:        sysctl_createv(clog, 0, NULL, NULL,
                    708:                       CTLFLAG_PERMANENT,
1.545     atatat    709:                       CTLTYPE_INT, "sse2", NULL,
                    710:                       NULL, 0, &i386_has_sse2, 0,
                    711:                       CTL_MACHDEP, CPU_SSE2, CTL_EOL);
1.554     lukem     712:        sysctl_createv(clog, 0, NULL, NULL,
                    713:                       CTLFLAG_PERMANENT,
                    714:                       CTLTYPE_STRING, "cpu_brand", NULL,
                    715:                       NULL, 0, &cpu_brand_string, 0,
                    716:                       CTL_MACHDEP, CTL_CREATE, CTL_EOL);
1.552     atatat    717:        sysctl_createv(clog, 0, NULL, NULL,
                    718:                       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1.621     tls       719:                       CTLTYPE_INT, "sparse_dump", NULL,
                    720:                       NULL, 0, &sparse_dump, 0,
                    721:                       CTL_MACHDEP, CTL_CREATE, CTL_EOL);
1.634     ad        722:        sysctl_createv(clog, 0, NULL, NULL,
                    723:                       CTLFLAG_PERMANENT,
                    724:                       CTLTYPE_QUAD, "tsc_freq", NULL,
                    725:                       NULL, 0, &tsc_freq, 0,
                    726:                       CTL_MACHDEP, CTL_CREATE, CTL_EOL);
1.104     cgd       727: }
1.151     christos  728:
1.534     christos  729: void *
                    730: getframe(struct lwp *l, int sig, int *onstack)
                    731: {
                    732:        struct proc *p = l->l_proc;
                    733:        struct trapframe *tf = l->l_md.md_regs;
                    734:
                    735:        /* Do we need to jump onto the signal stack? */
1.595     ad        736:        *onstack = (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0
1.534     christos  737:            && (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
                    738:        if (*onstack)
1.595     ad        739:                return (char *)l->l_sigstk.ss_sp + l->l_sigstk.ss_size;
1.534     christos  740: #ifdef VM86
                    741:        if (tf->tf_eflags & PSL_VM)
                    742:                return (void *)(tf->tf_esp + (tf->tf_ss << 4));
                    743:        else
                    744: #endif
                    745:                return (void *)tf->tf_esp;
                    746: }
                    747:
                    748: /*
                    749:  * Build context to run handler in.  We invoke the handler
                    750:  * directly, only returning via the trampoline.  Note the
                    751:  * trampoline version numbers are coordinated with machine-
                    752:  * dependent code in libc.
                    753:  */
                    754: void
                    755: buildcontext(struct lwp *l, int sel, void *catcher, void *fp)
                    756: {
                    757:        struct trapframe *tf = l->l_md.md_regs;
                    758:
1.622     bouyer    759: #ifndef XEN
1.612     ad        760:        tf->tf_gs = GSEL(GUGS_SEL, SEL_UPL);
                    761:        tf->tf_fs = GSEL(GUFS_SEL, SEL_UPL);
1.622     bouyer    762: #else
                    763:        tf->tf_gs = GSEL(GUDATA_SEL, SEL_UPL);
                    764:        tf->tf_fs = GSEL(GUDATA_SEL, SEL_UPL);
                    765: #endif
1.534     christos  766:        tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
                    767:        tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
                    768:        tf->tf_eip = (int)catcher;
                    769:        tf->tf_cs = GSEL(sel, SEL_UPL);
1.642     christos  770:        tf->tf_eflags &= ~PSL_CLEARSIG;
1.534     christos  771:        tf->tf_esp = (int)fp;
                    772:        tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
1.647     ad        773:
                    774:        /* Ensure FP state is reset, if FP is used. */
                    775:        l->l_md.md_flags &= ~MDL_USEDFPU;
1.534     christos  776: }
                    777:
                    778: static void
1.539     christos  779: sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
1.534     christos  780: {
                    781:        struct lwp *l = curlwp;
                    782:        struct proc *p = l->l_proc;
                    783:        struct pmap *pmap = vm_map_pmap(&p->p_vmspace->vm_map);
                    784:        int sel = pmap->pm_hiexec > I386_MAX_EXE_ADDR ?
                    785:            GUCODEBIG_SEL : GUCODE_SEL;
                    786:        struct sigacts *ps = p->p_sigacts;
1.595     ad        787:        int onstack, error;
1.534     christos  788:        int sig = ksi->ksi_signo;
                    789:        struct sigframe_siginfo *fp = getframe(l, sig, &onstack), frame;
                    790:        sig_t catcher = SIGACTION(p, sig).sa_handler;
                    791:        struct trapframe *tf = l->l_md.md_regs;
                    792:
1.629     ad        793:        KASSERT(mutex_owned(p->p_lock));
1.595     ad        794:
1.534     christos  795:        fp--;
                    796:
                    797:        /* Build stack frame for signal trampoline. */
                    798:        switch (ps->sa_sigdesc[sig].sd_vers) {
1.537     christos  799:        case 0:         /* handled by sendsig_sigcontext */
                    800:        case 1:         /* handled by sendsig_sigcontext */
1.534     christos  801:        default:        /* unknown version */
                    802:                printf("nsendsig: bad version %d\n",
                    803:                    ps->sa_sigdesc[sig].sd_vers);
                    804:                sigexit(l, SIGILL);
                    805:        case 2:
                    806:                break;
                    807:        }
                    808:
                    809:        frame.sf_ra = (int)ps->sa_sigdesc[sig].sd_tramp;
                    810:        frame.sf_signum = sig;
                    811:        frame.sf_sip = &fp->sf_si;
                    812:        frame.sf_ucp = &fp->sf_uc;
1.540     thorpej   813:        frame.sf_si._info = ksi->ksi_info;
1.534     christos  814:        frame.sf_uc.uc_flags = _UC_SIGMASK|_UC_VM;
                    815:        frame.sf_uc.uc_sigmask = *mask;
1.605     pooka     816:        frame.sf_uc.uc_link = l->l_ctxlink;
1.595     ad        817:        frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK)
1.534     christos  818:            ? _UC_SETSTACK : _UC_CLRSTACK;
                    819:        memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack));
                    820:
                    821:        if (tf->tf_eflags & PSL_VM)
                    822:                (*p->p_emul->e_syscall_intern)(p);
1.595     ad        823:        sendsig_reset(l, sig);
                    824:
1.629     ad        825:        mutex_exit(p->p_lock);
1.597     ad        826:        cpu_getmcontext(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags);
1.595     ad        827:        error = copyout(&frame, fp, sizeof(frame));
1.629     ad        828:        mutex_enter(p->p_lock);
1.595     ad        829:
                    830:        if (error != 0) {
1.534     christos  831:                /*
                    832:                 * Process has trashed its stack; give it an illegal
                    833:                 * instruction to halt it in its tracks.
                    834:                 */
                    835:                sigexit(l, SIGILL);
                    836:                /* NOTREACHED */
                    837:        }
                    838:
                    839:        buildcontext(l, sel, catcher, fp);
1.319     mycroft   840:
                    841:        /* Remember that we're now on the signal stack. */
                    842:        if (onstack)
1.595     ad        843:                l->l_sigstk.ss_flags |= SS_ONSTACK;
1.1       cgd       844: }
                    845:
1.534     christos  846: void
1.539     christos  847: sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
1.534     christos  848: {
1.595     ad        849:
1.629     ad        850:        KASSERT(mutex_owned(curproc->p_lock));
1.595     ad        851:
1.534     christos  852: #ifdef COMPAT_16
                    853:        if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2)
                    854:                sendsig_sigcontext(ksi, mask);
                    855:        else
                    856: #endif
                    857:                sendsig_siginfo(ksi, mask);
                    858: }
1.508     thorpej   859:
1.643     wrstuden  860: void
                    861: cpu_upcall(struct lwp *l, int type, int nevents, int ninterrupted, void *sas,
                    862:     void *ap, void *sp, sa_upcall_t upcall)
                    863: {
                    864:        struct pmap *pmap = vm_map_pmap(&l->l_proc->p_vmspace->vm_map);
                    865:        struct saframe *sf, frame;
                    866:        struct trapframe *tf;
                    867:
                    868:        tf = l->l_md.md_regs;
                    869:
                    870:        /* Finally, copy out the rest of the frame. */
                    871:        frame.sa_type = type;
                    872:        frame.sa_sas = sas;
                    873:        frame.sa_events = nevents;
                    874:        frame.sa_interrupted = ninterrupted;
                    875:        frame.sa_arg = ap;
                    876:        frame.sa_ra = 0;
                    877:
                    878:        sf = (struct saframe *)sp - 1;
                    879:        if (copyout(&frame, sf, sizeof(frame)) != 0) {
                    880:                /* Copying onto the stack didn't work. Die. */
                    881:                sigexit(l, SIGILL);
                    882:                /* NOTREACHED */
                    883:        }
                    884:
                    885:        tf->tf_eip = (int) upcall;
                    886:        tf->tf_esp = (int) sf;
                    887:        tf->tf_ebp = 0; /* indicate call-frame-top to debuggers */
                    888:        tf->tf_gs = GSEL(GUDATA_SEL, SEL_UPL);
                    889:        tf->tf_fs = GSEL(GUDATA_SEL, SEL_UPL);
                    890:        tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
                    891:        tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
                    892:        tf->tf_cs = pmap->pm_hiexec > I386_MAX_EXE_ADDR ?
                    893:            GSEL(GUCODEBIG_SEL, SEL_UPL) : GSEL(GUCODE_SEL, SEL_UPL);
                    894:        tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
                    895:        tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
                    896: }
                    897:
1.1       cgd       898: int    waittime = -1;
                    899:
1.32      andrew    900: void
1.586     christos  901: cpu_reboot(int howto, char *bootstr)
1.1       cgd       902: {
1.645     dyoung    903:        int s = 0;      /* XXX gcc */
1.1       cgd       904:
1.106     mycroft   905:        if (cold) {
1.193     mycroft   906:                howto |= RB_HALT;
                    907:                goto haltsys;
1.1       cgd       908:        }
1.193     mycroft   909:
1.106     mycroft   910:        boothowto = howto;
1.193     mycroft   911:        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
1.1       cgd       912:                waittime = 0;
1.150     mycroft   913:                vfs_shutdown();
1.521     dsl       914:                /*
                    915:                 * If we've been adjusting the clock, the todr
                    916:                 * will be out of synch; adjust it now.
                    917:                 */
                    918:                if (time_adjusted != 0)
                    919:                        resettodr();
1.1       cgd       920:        }
1.193     mycroft   921:
1.638     drochner  922:        /* Disable interrupts. */
1.645     dyoung    923:        s = splhigh();
1.638     drochner  924:
1.193     mycroft   925:        /* Do a dump if requested. */
1.638     drochner  926:        if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
1.193     mycroft   927:                dumpsys();
                    928:
                    929: haltsys:
                    930:        doshutdownhooks();
                    931:
1.645     dyoung    932:        if (!cold) {
                    933:                splx(s);
                    934:
                    935:                pmf_system_shutdown(boothowto);
                    936:
                    937:                splhigh();
                    938:        }
                    939:
1.484     fvdl      940: #ifdef MULTIPROCESSOR
1.514     fvdl      941:        x86_broadcast_ipi(X86_IPI_HALT);
1.484     fvdl      942: #endif
                    943:
1.307     thorpej   944:        if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
1.622     bouyer    945: #ifdef XEN
                    946:                HYPERVISOR_shutdown();
                    947:                for (;;);
                    948: #endif
1.587     jmcneill  949: #ifdef XBOX
                    950:                if (arch_i386_is_xbox) {
1.591     jmcneill  951:                        xbox_poweroff();
1.587     jmcneill  952:                        for (;;);
                    953:                }
                    954: #endif
1.473     tshiozak  955: #if NACPI > 0
1.530     kochi     956:                if (acpi_softc != NULL) {
                    957:                        acpi_enter_sleep_state(acpi_softc, ACPI_STATE_S5);
                    958:                        printf("WARNING: ACPI powerdown failed!\n");
                    959:                }
1.473     tshiozak  960: #endif
1.576     christos  961: #if NAPMBIOS > 0 && !defined(APM_NO_POWEROFF)
1.208     jtk       962:                /* turn off, if we can.  But try to turn disk off and
                    963:                 * wait a bit first--some disk drives are slow to clean up
                    964:                 * and users have reported disk corruption.
                    965:                 */
                    966:                delay(500000);
1.639     simonb    967:                apm_set_powstate(NULL, APM_DEV_DISK(APM_DEV_ALLUNITS),
                    968:                    APM_SYS_OFF);
1.208     jtk       969:                delay(500000);
1.576     christos  970:                apm_set_powstate(NULL, APM_DEV_ALLDEVS, APM_SYS_OFF);
1.531     kochi     971:                printf("WARNING: APM powerdown failed!\n");
1.307     thorpej   972:                /*
                    973:                 * RB_POWERDOWN implies RB_HALT... fall into it...
                    974:                 */
1.208     jtk       975: #endif
1.307     thorpej   976:        }
                    977:
                    978:        if (howto & RB_HALT) {
1.210     christos  979:                printf("\n");
                    980:                printf("The operating system has halted.\n");
                    981:                printf("Please press any key to reboot.\n\n");
1.517     jmmv      982:
                    983: #ifdef BEEP_ONHALT
                    984:                {
                    985:                        int c;
                    986:                        for (c = BEEP_ONHALT_COUNT; c > 0; c--) {
                    987:                                sysbeep(BEEP_ONHALT_PITCH,
1.565     simonb    988:                                        BEEP_ONHALT_PERIOD * hz / 1000);
1.517     jmmv      989:                                delay(BEEP_ONHALT_PERIOD * 1000);
                    990:                                sysbeep(0, BEEP_ONHALT_PERIOD * hz / 1000);
                    991:                                delay(BEEP_ONHALT_PERIOD * 1000);
                    992:                        }
                    993:                }
                    994: #endif
                    995:
1.300     drochner  996:                cnpollc(1);     /* for proper keyboard command handling */
1.512     perry     997:                if (cngetc() == 0) {
                    998:                        /* no console attached, so just hlt */
                    999:                        for(;;) {
1.608     ad       1000:                                x86_hlt();
1.512     perry    1001:                        }
                   1002:                }
1.300     drochner 1003:                cnpollc(0);
1.1       cgd      1004:        }
1.193     mycroft  1005:
1.210     christos 1006:        printf("rebooting...\n");
1.328     bouyer   1007:        if (cpureset_delay > 0)
                   1008:                delay(cpureset_delay * 1000);
1.1       cgd      1009:        cpu_reset();
                   1010:        for(;;) ;
                   1011:        /*NOTREACHED*/
                   1012: }
                   1013:
1.116     gwr      1014: /*
1.1       cgd      1015:  * Clear registers on exec
                   1016:  */
1.33      cgd      1017: void
1.551     junyoung 1018: setregs(struct lwp *l, struct exec_package *pack, u_long stack)
1.1       cgd      1019: {
1.533     chs      1020:        struct pmap *pmap = vm_map_pmap(&l->l_proc->p_vmspace->vm_map);
1.508     thorpej  1021:        struct pcb *pcb = &l->l_addr->u_pcb;
1.298     mycroft  1022:        struct trapframe *tf;
1.1       cgd      1023:
1.161     mycroft  1024: #if NNPX > 0
                   1025:        /* If we were using the FPU, forget about it. */
1.508     thorpej  1026:        if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
1.624     joerg    1027:                npxsave_lwp(l, false);
1.161     mycroft  1028: #endif
1.166     mycroft  1029:
1.178     mycroft  1030: #ifdef USER_LDT
1.508     thorpej  1031:        pmap_ldt_cleanup(l);
1.178     mycroft  1032: #endif
                   1033:
1.548     yamt     1034:        l->l_md.md_flags &= ~MDL_USEDFPU;
1.452     thorpej  1035:        if (i386_use_fxsave) {
1.450     thorpej  1036:                pcb->pcb_savefpu.sv_xmm.sv_env.en_cw = __NetBSD_NPXCW__;
1.452     thorpej  1037:                pcb->pcb_savefpu.sv_xmm.sv_env.en_mxcsr = __INITIAL_MXCSR__;
                   1038:        } else
1.450     thorpej  1039:                pcb->pcb_savefpu.sv_87.sv_env.en_cw = __NetBSD_NPXCW__;
1.613     ad       1040:        memcpy(pcb->pcb_fsd, &gdt[GUDATA_SEL], sizeof(pcb->pcb_fsd));
                   1041:        memcpy(pcb->pcb_gsd, &gdt[GUDATA_SEL], sizeof(pcb->pcb_gsd));
1.59      mycroft  1042:
1.508     thorpej  1043:        tf = l->l_md.md_regs;
1.622     bouyer   1044: #ifndef XEN
1.612     ad       1045:        tf->tf_gs = GSEL(GUGS_SEL, SEL_UPL);
                   1046:        tf->tf_fs = GSEL(GUFS_SEL, SEL_UPL);
1.622     bouyer   1047: #else
                   1048:        tf->tf_gs = LSEL(LUDATA_SEL, SEL_UPL);
                   1049:        tf->tf_fs = LSEL(LUDATA_SEL, SEL_UPL);
                   1050: #endif
1.154     mycroft  1051:        tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL);
                   1052:        tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL);
1.252     mycroft  1053:        tf->tf_edi = 0;
                   1054:        tf->tf_esi = 0;
1.154     mycroft  1055:        tf->tf_ebp = 0;
1.508     thorpej  1056:        tf->tf_ebx = (int)l->l_proc->p_psstr;
1.252     mycroft  1057:        tf->tf_edx = 0;
                   1058:        tf->tf_ecx = 0;
                   1059:        tf->tf_eax = 0;
1.154     mycroft  1060:        tf->tf_eip = pack->ep_entry;
1.533     chs      1061:        tf->tf_cs = pmap->pm_hiexec > I386_MAX_EXE_ADDR ?
                   1062:            LSEL(LUCODEBIG_SEL, SEL_UPL) : LSEL(LUCODE_SEL, SEL_UPL);
1.154     mycroft  1063:        tf->tf_eflags = PSL_USERSET;
                   1064:        tf->tf_esp = stack;
                   1065:        tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL);
1.1       cgd      1066: }
                   1067:
                   1068: /*
1.55      brezak   1069:  * Initialize segments and descriptor tables
1.1       cgd      1070:  */
                   1071:
1.516     fvdl     1072: union  descriptor *gdt, *ldt;
1.275     mycroft  1073: union  descriptor *pentium_idt;
1.573     yamt     1074: struct user *proc0paddr;
                   1075: extern vaddr_t proc0uarea;
1.49      brezak   1076:
1.178     mycroft  1077: void
1.551     junyoung 1078: setgate(struct gate_descriptor *gd, void *func, int args, int type, int dpl,
                   1079:     int sel)
1.178     mycroft  1080: {
1.1       cgd      1081:
1.178     mycroft  1082:        gd->gd_looffset = (int)func;
1.489     fvdl     1083:        gd->gd_selector = sel;
1.178     mycroft  1084:        gd->gd_stkcpy = args;
                   1085:        gd->gd_xx = 0;
                   1086:        gd->gd_type = type;
                   1087:        gd->gd_dpl = dpl;
                   1088:        gd->gd_p = 1;
                   1089:        gd->gd_hioffset = (int)func >> 16;
                   1090: }
                   1091:
                   1092: void
1.551     junyoung 1093: unsetgate(struct gate_descriptor *gd)
1.484     fvdl     1094: {
                   1095:        gd->gd_p = 0;
                   1096:        gd->gd_hioffset = 0;
                   1097:        gd->gd_looffset = 0;
                   1098:        gd->gd_selector = 0;
                   1099:        gd->gd_xx = 0;
                   1100:        gd->gd_stkcpy = 0;
                   1101:        gd->gd_type = 0;
                   1102:        gd->gd_dpl = 0;
                   1103: }
                   1104:
                   1105:
                   1106: void
1.551     junyoung 1107: setregion(struct region_descriptor *rd, void *base, size_t limit)
1.178     mycroft  1108: {
                   1109:
                   1110:        rd->rd_limit = (int)limit;
                   1111:        rd->rd_base = (int)base;
                   1112: }
1.1       cgd      1113:
1.174     mycroft  1114: void
1.620     yamt     1115: setsegment(struct segment_descriptor *sd, const void *base, size_t limit,
                   1116:     int type, int dpl, int def32, int gran)
1.174     mycroft  1117: {
1.1       cgd      1118:
1.174     mycroft  1119:        sd->sd_lolimit = (int)limit;
                   1120:        sd->sd_lobase = (int)base;
                   1121:        sd->sd_type = type;
                   1122:        sd->sd_dpl = dpl;
                   1123:        sd->sd_p = 1;
                   1124:        sd->sd_hilimit = (int)limit >> 16;
                   1125:        sd->sd_xx = 0;
                   1126:        sd->sd_def32 = def32;
                   1127:        sd->sd_gran = gran;
                   1128:        sd->sd_hibase = (int)base >> 24;
                   1129: }
1.1       cgd      1130:
                   1131: #define        IDTVEC(name)    __CONCAT(X, name)
1.542     junyoung 1132: typedef void (vector)(void);
1.299     mycroft  1133: extern vector IDTVEC(syscall);
                   1134: extern vector IDTVEC(osyscall);
                   1135: extern vector *IDTVEC(exceptions)[];
1.333     christos 1136: #ifdef COMPAT_SVR4
                   1137: extern vector IDTVEC(svr4_fasttrap);
                   1138: #endif /* COMPAT_SVR4 */
1.447     christos 1139: #ifdef COMPAT_MACH
                   1140: extern vector IDTVEC(mach_trap);
                   1141: #endif
1.622     bouyer   1142: #ifdef XEN
                   1143: #define MAX_XEN_IDT 128
                   1144: trap_info_t xen_idt[MAX_XEN_IDT];
                   1145: int xen_idt_idx;
                   1146: #endif
1.1       cgd      1147:
1.381     thorpej  1148: #define        KBTOB(x)        ((size_t)(x) * 1024UL)
1.619     joerg    1149: #define        MBTOB(x)        ((size_t)(x) * 1024UL * 1024UL)
1.381     thorpej  1150:
1.622     bouyer   1151: #ifndef XEN
1.484     fvdl     1152: void cpu_init_idt()
                   1153: {
                   1154:        struct region_descriptor region;
                   1155:        setregion(&region, pentium_idt, NIDT * sizeof(idt[0]) - 1);
1.565     simonb   1156:        lidt(&region);
1.484     fvdl     1157: }
                   1158:
1.433     kanaoka  1159: void
1.568     perry    1160: add_mem_cluster(uint64_t seg_start, uint64_t seg_end, uint32_t type)
1.433     kanaoka  1161: {
                   1162:        extern struct extent *iomem_ex;
1.619     joerg    1163:        uint64_t new_physmem;
1.492     kanaoka  1164:        int i;
1.433     kanaoka  1165:
                   1166:        if (seg_end > 0x100000000ULL) {
                   1167:                printf("WARNING: skipping large "
                   1168:                    "memory map entry: "
1.648     cegger   1169:                    "0x%"PRIx64"/0x%"PRIx64"/0x%x\n",
1.433     kanaoka  1170:                    seg_start,
                   1171:                    (seg_end - seg_start),
                   1172:                    type);
                   1173:                return;
                   1174:        }
                   1175:
                   1176:        /*
                   1177:         * XXX Chop the last page off the size so that
                   1178:         * XXX it can fit in avail_end.
                   1179:         */
                   1180:        if (seg_end == 0x100000000ULL)
                   1181:                seg_end -= PAGE_SIZE;
                   1182:
                   1183:        if (seg_end <= seg_start)
                   1184:                return;
                   1185:
1.492     kanaoka  1186:        for (i = 0; i < mem_cluster_cnt; i++) {
                   1187:                if ((mem_clusters[i].start == round_page(seg_start))
                   1188:                    && (mem_clusters[i].size
                   1189:                            == trunc_page(seg_end) - mem_clusters[i].start)) {
                   1190: #ifdef DEBUG_MEMLOAD
                   1191:                        printf("WARNING: skipping duplicate segment entry\n");
                   1192: #endif
                   1193:                        return;
                   1194:                }
                   1195:        }
                   1196:
1.433     kanaoka  1197:        /*
                   1198:         * Allocate the physical addresses used by RAM
                   1199:         * from the iomem extent map.  This is done before
                   1200:         * the addresses are page rounded just to make
                   1201:         * sure we get them all.
                   1202:         */
                   1203:        if (extent_alloc_region(iomem_ex, seg_start,
                   1204:            seg_end - seg_start, EX_NOWAIT)) {
                   1205:                /* XXX What should we do? */
                   1206:                printf("WARNING: CAN'T ALLOCATE "
                   1207:                    "MEMORY SEGMENT "
1.648     cegger   1208:                    "(0x%"PRIx64"/0x%"PRIx64"/0x%x) FROM "
1.433     kanaoka  1209:                    "IOMEM EXTENT MAP!\n",
                   1210:                    seg_start, seg_end - seg_start, type);
1.492     kanaoka  1211:                return;
1.433     kanaoka  1212:        }
                   1213:
                   1214:        /*
                   1215:         * If it's not free memory, skip it.
                   1216:         */
                   1217:        if (type != BIM_Memory)
                   1218:                return;
                   1219:
                   1220:        /* XXX XXX XXX */
                   1221:        if (mem_cluster_cnt >= VM_PHYSSEG_MAX)
1.579     cube     1222:                panic("init386: too many memory segments "
                   1223:                    "(increase VM_PHYSSEG_MAX)");
1.433     kanaoka  1224:
1.619     joerg    1225: #ifdef PHYSMEM_MAX_ADDR
                   1226:        if (seg_start >= MBTOB(PHYSMEM_MAX_ADDR))
                   1227:                return;
                   1228:        if (seg_end > MBTOB(PHYSMEM_MAX_ADDR))
                   1229:                seg_end = MBTOB(PHYSMEM_MAX_ADDR);
                   1230: #endif
                   1231:
1.433     kanaoka  1232:        seg_start = round_page(seg_start);
                   1233:        seg_end = trunc_page(seg_end);
                   1234:
                   1235:        if (seg_start == seg_end)
                   1236:                return;
                   1237:
                   1238:        mem_clusters[mem_cluster_cnt].start = seg_start;
1.619     joerg    1239:        new_physmem = physmem + atop(seg_end - seg_start);
                   1240:
                   1241: #ifdef PHYSMEM_MAX_SIZE
                   1242:        if (physmem >= atop(MBTOB(PHYSMEM_MAX_SIZE)))
                   1243:                return;
                   1244:        if (new_physmem > atop(MBTOB(PHYSMEM_MAX_SIZE))) {
                   1245:                seg_end = seg_start + MBTOB(PHYSMEM_MAX_SIZE) - ptoa(physmem);
                   1246:                new_physmem = atop(MBTOB(PHYSMEM_MAX_SIZE));
                   1247:        }
                   1248: #endif
                   1249:
                   1250:        mem_clusters[mem_cluster_cnt].size = seg_end - seg_start;
1.433     kanaoka  1251:
                   1252:        if (avail_end < seg_end)
                   1253:                avail_end = seg_end;
1.619     joerg    1254:        physmem = new_physmem;
1.433     kanaoka  1255:        mem_cluster_cnt++;
                   1256: }
1.622     bouyer   1257: #endif /* !XEN */
1.433     kanaoka  1258:
1.59      mycroft  1259: void
1.484     fvdl     1260: initgdt(union descriptor *tgdt)
                   1261: {
1.622     bouyer   1262: #ifdef XEN
1.625     bouyer   1263:        u_long  frames[16];
1.622     bouyer   1264: #else
1.484     fvdl     1265:        struct region_descriptor region;
                   1266:        gdt = tgdt;
                   1267:        memset(gdt, 0, NGDT*sizeof(*gdt));
1.622     bouyer   1268: #endif /* XEN */
1.484     fvdl     1269:        /* make gdt gates and memory segments */
                   1270:        setsegment(&gdt[GCODE_SEL].sd, 0, 0xfffff, SDT_MEMERA, SEL_KPL, 1, 1);
                   1271:        setsegment(&gdt[GDATA_SEL].sd, 0, 0xfffff, SDT_MEMRWA, SEL_KPL, 1, 1);
1.533     chs      1272:        setsegment(&gdt[GUCODE_SEL].sd, 0, x86_btop(I386_MAX_EXE_ADDR) - 1,
                   1273:            SDT_MEMERA, SEL_UPL, 1, 1);
1.615     ad       1274:        setsegment(&gdt[GUCODEBIG_SEL].sd, 0, 0xfffff,
1.484     fvdl     1275:            SDT_MEMERA, SEL_UPL, 1, 1);
1.615     ad       1276:        setsegment(&gdt[GUDATA_SEL].sd, 0, 0xfffff,
1.484     fvdl     1277:            SDT_MEMRWA, SEL_UPL, 1, 1);
                   1278: #ifdef COMPAT_MACH
                   1279:        setgate(&gdt[GMACHCALLS_SEL].gd, &IDTVEC(mach_trap), 1,
1.489     fvdl     1280:            SDT_SYS386CGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
1.484     fvdl     1281: #endif
                   1282: #if NBIOSCALL > 0
                   1283:        /* bios trampoline GDT entries */
                   1284:        setsegment(&gdt[GBIOSCODE_SEL].sd, 0, 0xfffff, SDT_MEMERA, SEL_KPL, 0,
                   1285:            0);
                   1286:        setsegment(&gdt[GBIOSDATA_SEL].sd, 0, 0xfffff, SDT_MEMRWA, SEL_KPL, 0,
                   1287:            0);
                   1288: #endif
1.615     ad       1289:        setsegment(&gdt[GCPU_SEL].sd, &cpu_info_primary, 0xfffff,
                   1290:            SDT_MEMRWA, SEL_KPL, 1, 1);
1.484     fvdl     1291:
1.622     bouyer   1292: #ifndef XEN
1.484     fvdl     1293:        setregion(&region, gdt, NGDT * sizeof(gdt[0]) - 1);
                   1294:        lgdt(&region);
1.622     bouyer   1295: #else /* !XEN */
                   1296:        frames[0] = xpmap_ptom((uint32_t)gdt - KERNBASE) >> PAGE_SHIFT;
                   1297:        pmap_kenter_pa((vaddr_t)gdt, (uint32_t)gdt - KERNBASE, VM_PROT_READ);
                   1298: #ifdef XEN3
                   1299:        XENPRINTK(("loading gdt %lx, %d entries\n", frames[0] << PAGE_SHIFT,
                   1300:            NGDT));
                   1301:        if (HYPERVISOR_set_gdt(frames, NGDT /* XXX is it right ? */))
                   1302:                panic("HYPERVISOR_set_gdt failed!\n");
                   1303: #else
                   1304:        XENPRINTK(("loading gdt %lx, %d entries\n", frames[0] << PAGE_SHIFT,
                   1305:            LAST_RESERVED_GDT_ENTRY + 1));
                   1306:        if (HYPERVISOR_set_gdt(frames, LAST_RESERVED_GDT_ENTRY + 1))
                   1307:                panic("HYPERVISOR_set_gdt failed!\n");
                   1308: #endif
                   1309:        lgdt_finish();
                   1310:
                   1311: #endif /* !XEN */
1.484     fvdl     1312: }
                   1313:
1.617     jmcneill 1314: static void
                   1315: init386_msgbuf(void)
                   1316: {
                   1317:        /* Message buffer is located at end of core. */
                   1318:        struct vm_physseg *vps;
                   1319:        psize_t sz = round_page(MSGBUFSIZE);
                   1320:        psize_t reqsz = sz;
                   1321:        unsigned int x;
                   1322:
                   1323:  search_again:
                   1324:        vps = NULL;
                   1325:        for (x = 0; x < vm_nphysseg; ++x) {
                   1326:                vps = &vm_physmem[x];
                   1327:                if (ptoa(vps->avail_end) == avail_end) {
                   1328:                        break;
                   1329:                }
                   1330:        }
                   1331:        if (x == vm_nphysseg)
                   1332:                panic("init386: can't find end of memory");
                   1333:
                   1334:        /* Shrink so it'll fit in the last segment. */
                   1335:        if (vps->avail_end - vps->avail_start < atop(sz))
                   1336:                sz = ptoa(vps->avail_end - vps->avail_start);
                   1337:
                   1338:        vps->avail_end -= atop(sz);
                   1339:        vps->end -= atop(sz);
                   1340:        msgbuf_p_seg[msgbuf_p_cnt].sz = sz;
                   1341:        msgbuf_p_seg[msgbuf_p_cnt++].paddr = ptoa(vps->avail_end);
                   1342:
                   1343:        /* Remove the last segment if it now has no pages. */
                   1344:        if (vps->start == vps->end) {
                   1345:                for (--vm_nphysseg; x < vm_nphysseg; x++)
                   1346:                        vm_physmem[x] = vm_physmem[x + 1];
                   1347:        }
                   1348:
                   1349:        /* Now find where the new avail_end is. */
                   1350:        for (avail_end = 0, x = 0; x < vm_nphysseg; x++)
                   1351:                if (vm_physmem[x].avail_end > avail_end)
                   1352:                        avail_end = vm_physmem[x].avail_end;
                   1353:        avail_end = ptoa(avail_end);
                   1354:
                   1355:        if (sz == reqsz)
                   1356:                return;
                   1357:
                   1358:        reqsz -= sz;
                   1359:        if (msgbuf_p_cnt == VM_PHYSSEG_MAX) {
                   1360:                /* No more segments available, bail out. */
                   1361:                printf("WARNING: MSGBUFSIZE (%zu) too large, using %zu.\n",
                   1362:                    (size_t)MSGBUFSIZE, (size_t)(MSGBUFSIZE - reqsz));
                   1363:                return;
                   1364:        }
                   1365:
                   1366:        sz = reqsz;
                   1367:        goto search_again;
                   1368: }
                   1369:
1.622     bouyer   1370: #ifndef XEN
1.617     jmcneill 1371: static void
                   1372: init386_pte0(void)
                   1373: {
                   1374:        paddr_t paddr;
                   1375:        vaddr_t vaddr;
                   1376:
                   1377:        paddr = 4 * PAGE_SIZE;
                   1378:        vaddr = (vaddr_t)vtopte(0);
                   1379:        pmap_kenter_pa(vaddr, paddr, VM_PROT_READ | VM_PROT_WRITE);
                   1380:        pmap_update(pmap_kernel());
                   1381:        /* make sure it is clean before using */
                   1382:        memset((void *)vaddr, 0, PAGE_SIZE);
                   1383: }
1.622     bouyer   1384: #endif /* !XEN */
1.617     jmcneill 1385:
                   1386: static void
                   1387: init386_ksyms(void)
                   1388: {
1.649   ! ad       1389: #if NKSYMS || defined(DDB) || defined(MODULAR)
1.617     jmcneill 1390:        extern int end;
                   1391:        struct btinfo_symtab *symtab;
                   1392:
                   1393: #ifdef DDB
                   1394:        db_machine_init();
                   1395: #endif
                   1396:
                   1397: #if defined(MULTIBOOT)
                   1398:        if (multiboot_ksyms_init())
                   1399:                return;
                   1400: #endif
                   1401:
                   1402:        if ((symtab = lookup_bootinfo(BTINFO_SYMTAB)) == NULL) {
                   1403:                ksyms_init(*(int *)&end, ((int *)&end) + 1, esym);
                   1404:                return;
                   1405:        }
                   1406:
                   1407:        symtab->ssym += KERNBASE;
                   1408:        symtab->esym += KERNBASE;
                   1409:        ksyms_init(symtab->nsym, (int *)symtab->ssym, (int *)symtab->esym);
                   1410: #endif
                   1411: }
                   1412:
1.484     fvdl     1413: void
1.551     junyoung 1414: init386(paddr_t first_avail)
1.2       cgd      1415: {
1.648     cegger   1416:        extern void consinit(void);
                   1417:        int x;
1.622     bouyer   1418: #ifndef XEN
1.648     cegger   1419:        int first16q;
1.484     fvdl     1420:        union descriptor *tgdt;
1.375     drochner 1421:        extern struct extent *iomem_ex;
1.381     thorpej  1422:        struct region_descriptor region;
1.568     perry    1423:        uint64_t seg_start, seg_end;
                   1424:        uint64_t seg_start1, seg_end1;
1.648     cegger   1425:        struct btinfo_memmap *bim;
                   1426:        uint64_t addr, size;
1.622     bouyer   1427: #endif
1.436     jdolecek 1428: #if NBIOSCALL > 0
                   1429:        extern int biostramp_image_size;
                   1430:        extern u_char biostramp_image[];
                   1431: #endif
1.1       cgd      1432:
1.622     bouyer   1433: #ifdef XEN
                   1434:        XENPRINTK(("HYPERVISOR_shared_info %p (%x)\n", HYPERVISOR_shared_info,
                   1435:            xen_start_info.shared_info));
1.628     cegger   1436:        KASSERT(HYPERVISOR_shared_info != NULL);
                   1437:        cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0];
1.622     bouyer   1438: #endif
1.635     ad       1439:        cpu_probe(&cpu_info_primary);
1.484     fvdl     1440:        cpu_feature = cpu_info_primary.ci_feature_flags;
1.553     lukem    1441:        cpu_feature2 = cpu_info_primary.ci_feature2_flags;
1.596     daniel   1442:        cpu_feature_padlock = cpu_info_primary.ci_padlock_flags;
1.484     fvdl     1443:
1.573     yamt     1444:        proc0paddr = UAREA_TO_USER(proc0uarea);
1.508     thorpej  1445:        lwp0.l_addr = proc0paddr;
1.275     mycroft  1446:
1.622     bouyer   1447: #ifdef XEN
                   1448:        /* not on Xen... */
                   1449:        cpu_feature &= ~(CPUID_PGE|CPUID_PSE|CPUID_MTRR|CPUID_FXSR|CPUID_NOX);
                   1450:        lwp0.l_addr->u_pcb.pcb_cr3 = PDPpaddr - KERNBASE;
                   1451:        __PRINTK(("pcb_cr3 0x%lx cr3 0x%lx\n",
                   1452:            PDPpaddr - KERNBASE, xpmap_ptom(PDPpaddr - KERNBASE)));
                   1453:        XENPRINTK(("proc0paddr %p first_avail %p\n",
1.625     bouyer   1454:            proc0paddr, (void *)(long)first_avail));
1.622     bouyer   1455:        XENPRINTK(("ptdpaddr %p atdevbase %p\n", (void *)PDPpaddr,
                   1456:            (void *)atdevbase));
                   1457: #endif
                   1458:
                   1459:
1.587     jmcneill 1460: #ifdef XBOX
                   1461:        /*
1.594     jmcneill 1462:         * From Rink Springer @ FreeBSD:
                   1463:         *
1.587     jmcneill 1464:         * The following code queries the PCI ID of 0:0:0. For the XBOX,
                   1465:         * This should be 0x10de / 0x02a5.
                   1466:         *
                   1467:         * This is exactly what Linux does.
                   1468:         */
                   1469:        outl(0xcf8, 0x80000000);
                   1470:        if (inl(0xcfc) == 0x02a510de) {
                   1471:                arch_i386_is_xbox = 1;
                   1472:                xbox_lcd_init();
                   1473:                xbox_lcd_writetext("NetBSD/i386 ");
                   1474:
                   1475:                /*
                   1476:                 * We are an XBOX, but we may have either 64MB or 128MB of
                   1477:                 * memory. The PCI host bridge should be programmed for this,
                   1478:                 * so we just query it.
                   1479:                 */
                   1480:                outl(0xcf8, 0x80000084);
                   1481:                arch_i386_xbox_memsize = (inl(0xcfc) == 0x7FFFFFF) ? 128 : 64;
                   1482:        }
                   1483: #endif /* XBOX */
                   1484:
1.622     bouyer   1485: #if NISA > 0 || NPCI > 0
1.514     fvdl     1486:        x86_bus_space_init();
1.622     bouyer   1487: #endif
                   1488: #ifdef XEN
                   1489:        xen_parse_cmdline(XEN_PARSE_BOOTFLAGS, NULL);
                   1490: #endif
                   1491:
1.401     thorpej  1492:        /*
                   1493:         * Initailize PAGE_SIZE-dependent variables.
                   1494:         */
                   1495:        uvm_setpagesize();
1.450     thorpej  1496:
                   1497:        /*
                   1498:         * Saving SSE registers won't work if the save area isn't
                   1499:         * 16-byte aligned.
                   1500:         */
                   1501:        if (offsetof(struct user, u_pcb.pcb_savefpu) & 0xf)
                   1502:                panic("init386: pcb_savefpu not 16-byte aligned");
1.440     thorpej  1503:
                   1504:        /*
                   1505:         * Start with 2 color bins -- this is just a guess to get us
                   1506:         * started.  We'll recolor when we determine the largest cache
                   1507:         * sizes on the system.
                   1508:         */
                   1509:        uvmexp.ncolors = 2;
1.401     thorpej  1510:
1.622     bouyer   1511: #ifndef XEN
1.473     tshiozak 1512:        /*
1.617     jmcneill 1513:         * Low memory reservations:
                   1514:         * Page 0:      BIOS data
                   1515:         * Page 1:      BIOS callback
                   1516:         * Page 2:      MP bootstrap
                   1517:         * Page 3:      ACPI wakeup code
                   1518:         * Page 4:      Temporary page table for 0MB-4MB
                   1519:         * Page 5:      Temporary page directory
1.473     tshiozak 1520:         */
1.617     jmcneill 1521:        avail_start = 6 * PAGE_SIZE;
1.622     bouyer   1522: #else /* !XEN */
                   1523:        /* steal one page for gdt */
1.625     bouyer   1524:        gdt = (void *)((u_long)first_avail + KERNBASE);
1.622     bouyer   1525:        first_avail += PAGE_SIZE;
                   1526:        /* Make sure the end of the space used by the kernel is rounded. */
                   1527:        first_avail = round_page(first_avail);
                   1528:        avail_start = first_avail;
                   1529:        avail_end = ptoa(xen_start_info.nr_pages) + XPMAP_OFFSET;
                   1530:        pmap_pa_start = (KERNTEXTOFF - KERNBASE);
                   1531:        pmap_pa_end = avail_end;
                   1532:        mem_clusters[0].start = avail_start;
                   1533:        mem_clusters[0].size = avail_end - avail_start;
                   1534:        mem_cluster_cnt++;
                   1535:        physmem += xen_start_info.nr_pages;
                   1536:        uvmexp.wired += atop(avail_start);
                   1537:        /*
                   1538:         * initgdt() has to be done before consinit(), so that %fs is properly
                   1539:         * initialised. initgdt() uses pmap_kenter_pa so it can't be called
                   1540:         * before the above variables are set.
                   1541:         */
                   1542:        initgdt(NULL);
                   1543: #endif /* XEN */
                   1544:        consinit();     /* XXX SHOULD NOT BE DONE HERE */
1.414     thorpej  1545:
1.492     kanaoka  1546: #ifdef DEBUG_MEMLOAD
                   1547:        printf("mem_cluster_count: %d\n", mem_cluster_cnt);
                   1548: #endif
                   1549:
1.401     thorpej  1550:        /*
                   1551:         * Call pmap initialization to make new kernel address space.
                   1552:         * We must do this before loading pages into the VM system.
                   1553:         */
1.314     thorpej  1554:        pmap_bootstrap((vaddr_t)atdevbase + IOM_SIZE);
1.2       cgd      1555:
1.622     bouyer   1556: #ifndef XEN
1.401     thorpej  1557:        /*
                   1558:         * Check to see if we have a memory map from the BIOS (passed
                   1559:         * to us by the boot program.
                   1560:         */
1.577     mrg      1561:        if ((biosmem_implicit || (biosbasemem == 0 && biosextmem == 0)) &&
1.575     mrg      1562:            (bim = lookup_bootinfo(BTINFO_MEMMAP)) != NULL && bim->num > 0) {
1.463     enami    1563: #ifdef DEBUG_MEMLOAD
1.401     thorpej  1564:                printf("BIOS MEMORY MAP (%d ENTRIES):\n", bim->num);
                   1565: #endif
                   1566:                for (x = 0; x < bim->num; x++) {
1.648     cegger   1567:                        addr = bim->entry[x].addr;
                   1568:                        size = bim->entry[x].size;
1.463     enami    1569: #ifdef DEBUG_MEMLOAD
1.648     cegger   1570:                        printf("    addr 0x%"PRIx64"  size 0x%"PRIx64
                   1571:                                "  type 0x%x\n",
                   1572:                                addr, size, bim->entry[x].type);
1.401     thorpej  1573: #endif
                   1574:
                   1575:                        /*
                   1576:                         * If the segment is not memory, skip it.
                   1577:                         */
                   1578:                        switch (bim->entry[x].type) {
                   1579:                        case BIM_Memory:
                   1580:                        case BIM_ACPI:
                   1581:                        case BIM_NVS:
                   1582:                                break;
                   1583:                        default:
                   1584:                                continue;
                   1585:                        }
                   1586:
                   1587:                        /*
1.604     briggs   1588:                         * If the segment is smaller than a page, skip it.
                   1589:                         */
1.648     cegger   1590:                        if (size < NBPG)
1.604     briggs   1591:                                continue;
                   1592:
                   1593:                        /*
1.401     thorpej  1594:                         * Sanity check the entry.
                   1595:                         * XXX Need to handle uint64_t in extent code
                   1596:                         * XXX and 64-bit physical addresses in i386
                   1597:                         * XXX port.
                   1598:                         */
1.648     cegger   1599:                        seg_start = addr;
                   1600:                        seg_end = addr + size;
1.401     thorpej  1601:
1.432     kanaoka  1602:                        /*
1.433     kanaoka  1603:                         *   Avoid Compatibility Holes.
                   1604:                         * XXX  Holes within memory space that allow access
                   1605:                         * XXX to be directed to the PC-compatible frame buffer
1.484     fvdl     1606:                         * XXX (0xa0000-0xbffff),to adapter ROM space
1.433     kanaoka  1607:                         * XXX (0xc0000-0xdffff), and to system BIOS space
                   1608:                         * XXX (0xe0000-0xfffff).
                   1609:                         * XXX  Some laptop(for example,Toshiba Satellite2550X)
                   1610:                         * XXX report this area and occurred problems,
                   1611:                         * XXX so we avoid this area.
1.432     kanaoka  1612:                         */
1.433     kanaoka  1613:                        if (seg_start < 0x100000 && seg_end > 0xa0000) {
                   1614:                                printf("WARNING: memory map entry overlaps "
                   1615:                                    "with ``Compatibility Holes'': "
1.648     cegger   1616:                                    "0x%"PRIx64"/0x%"PRIx64"/0x%x\n", seg_start,
1.433     kanaoka  1617:                                    seg_end - seg_start, bim->entry[x].type);
                   1618:                                add_mem_cluster(seg_start, 0xa0000,
                   1619:                                    bim->entry[x].type);
                   1620:                                add_mem_cluster(0x100000, seg_end,
1.401     thorpej  1621:                                    bim->entry[x].type);
1.433     kanaoka  1622:                        } else
                   1623:                                add_mem_cluster(seg_start, seg_end,
1.401     thorpej  1624:                                    bim->entry[x].type);
                   1625:                }
1.421     aymeric  1626:        }
1.575     mrg      1627:
1.421     aymeric  1628:        /*
                   1629:         * If the loop above didn't find any valid segment, fall back to
                   1630:         * former code.
                   1631:         */
                   1632:        if (mem_cluster_cnt == 0) {
1.401     thorpej  1633:                /*
                   1634:                 * Allocate the physical addresses used by RAM from the iomem
                   1635:                 * extent map.  This is done before the addresses are
                   1636:                 * page rounded just to make sure we get them all.
                   1637:                 */
                   1638:                if (extent_alloc_region(iomem_ex, 0, KBTOB(biosbasemem),
                   1639:                    EX_NOWAIT)) {
                   1640:                        /* XXX What should we do? */
                   1641:                        printf("WARNING: CAN'T ALLOCATE BASE MEMORY FROM "
                   1642:                            "IOMEM EXTENT MAP!\n");
                   1643:                }
                   1644:                mem_clusters[0].start = 0;
                   1645:                mem_clusters[0].size = trunc_page(KBTOB(biosbasemem));
                   1646:                physmem += atop(mem_clusters[0].size);
                   1647:                if (extent_alloc_region(iomem_ex, IOM_END, KBTOB(biosextmem),
                   1648:                    EX_NOWAIT)) {
                   1649:                        /* XXX What should we do? */
                   1650:                        printf("WARNING: CAN'T ALLOCATE EXTENDED MEMORY FROM "
                   1651:                            "IOMEM EXTENT MAP!\n");
                   1652:                }
                   1653: #if NISADMA > 0
                   1654:                /*
                   1655:                 * Some motherboards/BIOSes remap the 384K of RAM that would
                   1656:                 * normally be covered by the ISA hole to the end of memory
                   1657:                 * so that it can be used.  However, on a 16M system, this
                   1658:                 * would cause bounce buffers to be allocated and used.
                   1659:                 * This is not desirable behaviour, as more than 384K of
                   1660:                 * bounce buffers might be allocated.  As a work-around,
                   1661:                 * we round memory down to the nearest 1M boundary if
                   1662:                 * we're using any isadma devices and the remapped memory
                   1663:                 * is what puts us over 16M.
                   1664:                 */
                   1665:                if (biosextmem > (15*1024) && biosextmem < (16*1024)) {
                   1666:                        char pbuf[9];
                   1667:
                   1668:                        format_bytes(pbuf, sizeof(pbuf),
                   1669:                            biosextmem - (15*1024));
                   1670:                        printf("Warning: ignoring %s of remapped memory\n",
                   1671:                            pbuf);
                   1672:                        biosextmem = (15*1024);
                   1673:                }
                   1674: #endif
                   1675:                mem_clusters[1].start = IOM_END;
                   1676:                mem_clusters[1].size = trunc_page(KBTOB(biosextmem));
                   1677:                physmem += atop(mem_clusters[1].size);
                   1678:
                   1679:                mem_cluster_cnt = 2;
                   1680:
                   1681:                avail_end = IOM_END + trunc_page(KBTOB(biosextmem));
                   1682:        }
1.648     cegger   1683:
1.401     thorpej  1684:        /*
                   1685:         * If we have 16M of RAM or less, just put it all on
                   1686:         * the default free list.  Otherwise, put the first
                   1687:         * 16M of RAM on a lower priority free list (so that
                   1688:         * all of the ISA DMA'able memory won't be eaten up
                   1689:         * first-off).
                   1690:         */
                   1691:        if (avail_end <= (16 * 1024 * 1024))
                   1692:                first16q = VM_FREELIST_DEFAULT;
                   1693:        else
                   1694:                first16q = VM_FREELIST_FIRST16;
                   1695:
                   1696:        /* Make sure the end of the space used by the kernel is rounded. */
                   1697:        first_avail = round_page(first_avail);
                   1698:
                   1699:        /*
                   1700:         * Now, load the memory clusters (which have already been
                   1701:         * rounded and truncated) into the VM system.
                   1702:         *
                   1703:         * NOTE: WE ASSUME THAT MEMORY STARTS AT 0 AND THAT THE KERNEL
                   1704:         * IS LOADED AT IOM_END (1M).
                   1705:         */
                   1706:        for (x = 0; x < mem_cluster_cnt; x++) {
                   1707:                seg_start = mem_clusters[x].start;
                   1708:                seg_end = mem_clusters[x].start + mem_clusters[x].size;
                   1709:                seg_start1 = 0;
                   1710:                seg_end1 = 0;
                   1711:
                   1712:                /*
                   1713:                 * Skip memory before our available starting point.
                   1714:                 */
                   1715:                if (seg_end <= avail_start)
                   1716:                        continue;
                   1717:
                   1718:                if (avail_start >= seg_start && avail_start < seg_end) {
                   1719:                        if (seg_start != 0)
                   1720:                                panic("init386: memory doesn't start at 0");
                   1721:                        seg_start = avail_start;
                   1722:                        if (seg_start == seg_end)
                   1723:                                continue;
                   1724:                }
                   1725:
                   1726:                /*
                   1727:                 * If this segment contains the kernel, split it
                   1728:                 * in two, around the kernel.
                   1729:                 */
                   1730:                if (seg_start <= IOM_END && first_avail <= seg_end) {
                   1731:                        seg_start1 = first_avail;
                   1732:                        seg_end1 = seg_end;
                   1733:                        seg_end = IOM_END;
                   1734:                }
                   1735:
                   1736:                /* First hunk */
                   1737:                if (seg_start != seg_end) {
1.480     erh      1738:                        if (seg_start < (16 * 1024 * 1024) &&
1.401     thorpej  1739:                            first16q != VM_FREELIST_DEFAULT) {
1.568     perry    1740:                                uint64_t tmp;
1.401     thorpej  1741:
                   1742:                                if (seg_end > (16 * 1024 * 1024))
                   1743:                                        tmp = (16 * 1024 * 1024);
                   1744:                                else
                   1745:                                        tmp = seg_end;
1.492     kanaoka  1746:
                   1747:                                if (tmp != seg_start) {
1.463     enami    1748: #ifdef DEBUG_MEMLOAD
1.648     cegger   1749:                                        printf("loading 0x%"PRIx64"-0x%"PRIx64
                   1750:                                            " (0x%lx-0x%lx)\n",
1.492     kanaoka  1751:                                            seg_start, tmp,
                   1752:                                            atop(seg_start), atop(tmp));
                   1753: #endif
                   1754:                                        uvm_page_physload(atop(seg_start),
                   1755:                                            atop(tmp), atop(seg_start),
                   1756:                                            atop(tmp), first16q);
                   1757:                                }
1.401     thorpej  1758:                                seg_start = tmp;
                   1759:                        }
1.411     enami    1760:
                   1761:                        if (seg_start != seg_end) {
1.463     enami    1762: #ifdef DEBUG_MEMLOAD
1.648     cegger   1763:                                printf("loading 0x%"PRIx64"-0x%"PRIx64
                   1764:                                    " (0x%lx-0x%lx)\n",
1.411     enami    1765:                                    seg_start, seg_end,
                   1766:                                    atop(seg_start), atop(seg_end));
                   1767: #endif
                   1768:                                uvm_page_physload(atop(seg_start),
                   1769:                                    atop(seg_end), atop(seg_start),
                   1770:                                    atop(seg_end), VM_FREELIST_DEFAULT);
                   1771:                        }
1.401     thorpej  1772:                }
                   1773:
                   1774:                /* Second hunk */
                   1775:                if (seg_start1 != seg_end1) {
1.480     erh      1776:                        if (seg_start1 < (16 * 1024 * 1024) &&
1.401     thorpej  1777:                            first16q != VM_FREELIST_DEFAULT) {
1.568     perry    1778:                                uint64_t tmp;
1.401     thorpej  1779:
                   1780:                                if (seg_end1 > (16 * 1024 * 1024))
                   1781:                                        tmp = (16 * 1024 * 1024);
                   1782:                                else
                   1783:                                        tmp = seg_end1;
1.492     kanaoka  1784:
                   1785:                                if (tmp != seg_start1) {
1.463     enami    1786: #ifdef DEBUG_MEMLOAD
1.648     cegger   1787:                                        printf("loading 0x%"PRIx64"-0x%"PRIx64
                   1788:                                            " (0x%lx-0x%lx)\n",
1.492     kanaoka  1789:                                            seg_start1, tmp,
                   1790:                                            atop(seg_start1), atop(tmp));
                   1791: #endif
                   1792:                                        uvm_page_physload(atop(seg_start1),
                   1793:                                            atop(tmp), atop(seg_start1),
                   1794:                                            atop(tmp), first16q);
                   1795:                                }
1.401     thorpej  1796:                                seg_start1 = tmp;
                   1797:                        }
1.412     enami    1798:
                   1799:                        if (seg_start1 != seg_end1) {
1.463     enami    1800: #ifdef DEBUG_MEMLOAD
1.648     cegger   1801:                                printf("loading 0x%"PRIx64"-0x%"PRIx64
                   1802:                                    " (0x%lx-0x%lx)\n",
1.412     enami    1803:                                    seg_start1, seg_end1,
                   1804:                                    atop(seg_start1), atop(seg_end1));
                   1805: #endif
                   1806:                                uvm_page_physload(atop(seg_start1),
                   1807:                                    atop(seg_end1), atop(seg_start1),
                   1808:                                    atop(seg_end1), VM_FREELIST_DEFAULT);
                   1809:                        }
1.401     thorpej  1810:                }
                   1811:        }
1.622     bouyer   1812: #else /* !XEN */
                   1813:        XENPRINTK(("load the memory cluster %p(%d) - %p(%ld)\n",
1.625     bouyer   1814:            (void *)(long)avail_start, (int)atop(avail_start),
                   1815:            (void *)(long)avail_end, (int)atop(avail_end)));
1.622     bouyer   1816:        uvm_page_physload(atop(avail_start), atop(avail_end),
                   1817:            atop(avail_start), atop(avail_end),
                   1818:            VM_FREELIST_DEFAULT);
                   1819: #endif /* !XEN */
1.401     thorpej  1820:
1.617     jmcneill 1821:        init386_msgbuf();
1.622     bouyer   1822:
                   1823: #ifndef XEN
1.401     thorpej  1824:        /*
1.617     jmcneill 1825:         * XXX Remove this
                   1826:         *
                   1827:         * Setup a temporary Page Table Entry to allow identity mappings of
                   1828:         * the real mode address. This is required by:
                   1829:         * - bioscall
                   1830:         * - MP bootstrap
                   1831:         * - ACPI wakecode
1.473     tshiozak 1832:         */
1.617     jmcneill 1833:        init386_pte0();
1.473     tshiozak 1834:
1.295     drochner 1835: #if NBIOSCALL > 0
1.617     jmcneill 1836:        KASSERT(biostramp_image_size <= PAGE_SIZE);
1.436     jdolecek 1837:        pmap_kenter_pa((vaddr_t)BIOSTRAMP_BASE, /* virtual */
                   1838:                       (paddr_t)BIOSTRAMP_BASE, /* physical */
                   1839:                       VM_PROT_ALL);            /* protection */
1.456     chris    1840:        pmap_update(pmap_kernel());
1.600     christos 1841:        memcpy((void *)BIOSTRAMP_BASE, biostramp_image, biostramp_image_size);
1.295     drochner 1842: #endif
1.622     bouyer   1843: #endif /* !XEN */
1.59      mycroft  1844:
1.561     yamt     1845:        pmap_kenter_pa(idt_vaddr, idt_paddr, VM_PROT_READ|VM_PROT_WRITE);
1.456     chris    1846:        pmap_update(pmap_kernel());
1.484     fvdl     1847:        memset((void *)idt_vaddr, 0, PAGE_SIZE);
                   1848:
1.622     bouyer   1849:
                   1850: #ifndef XEN
1.618     yamt     1851:        idt_init();
1.622     bouyer   1852:
1.516     fvdl     1853:        idt = (struct gate_descriptor *)idt_vaddr;
1.561     yamt     1854:        pmap_kenter_pa(pentium_idt_vaddr, idt_paddr, VM_PROT_READ);
1.607     ad       1855:        pmap_update(pmap_kernel());
1.275     mycroft  1856:        pentium_idt = (union descriptor *)pentium_idt_vaddr;
1.484     fvdl     1857:
                   1858:        tgdt = gdt;
1.516     fvdl     1859:        gdt = (union descriptor *)
                   1860:                    ((char *)idt + NIDT * sizeof (struct gate_descriptor));
1.275     mycroft  1861:        ldt = gdt + NGDT;
                   1862:
1.484     fvdl     1863:        memcpy(gdt, tgdt, NGDT*sizeof(*gdt));
1.275     mycroft  1864:
                   1865:        setsegment(&gdt[GLDT_SEL].sd, ldt, NLDT * sizeof(ldt[0]) - 1,
                   1866:            SDT_SYSLDT, SEL_KPL, 0, 0);
1.622     bouyer   1867: #else
                   1868:        HYPERVISOR_set_callbacks(
                   1869:            GSEL(GCODE_SEL, SEL_KPL), (unsigned long)hypervisor_callback,
                   1870:            GSEL(GCODE_SEL, SEL_KPL), (unsigned long)failsafe_callback);
                   1871:
                   1872:        ldt = (union descriptor *)idt_vaddr;
                   1873: #endif /* XEN */
1.275     mycroft  1874:
                   1875:        /* make ldt gates and memory segments */
                   1876:        setgate(&ldt[LSYS5CALLS_SEL].gd, &IDTVEC(osyscall), 1,
1.489     fvdl     1877:            SDT_SYS386CGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
1.447     christos 1878:
1.275     mycroft  1879:        ldt[LUCODE_SEL] = gdt[GUCODE_SEL];
1.533     chs      1880:        ldt[LUCODEBIG_SEL] = gdt[GUCODEBIG_SEL];
1.275     mycroft  1881:        ldt[LUDATA_SEL] = gdt[GUDATA_SEL];
1.324     christos 1882:        ldt[LSOL26CALLS_SEL] = ldt[LBSDICALLS_SEL] = ldt[LSYS5CALLS_SEL];
1.275     mycroft  1883:
1.622     bouyer   1884: #ifndef XEN
1.275     mycroft  1885:        /* exceptions */
1.498     fvdl     1886:        for (x = 0; x < 32; x++) {
1.618     yamt     1887:                idt_vec_reserve(x);
1.630     ad       1888:                setgate(&idt[x], IDTVEC(exceptions)[x], 0,
                   1889:                    (x == 7 || x == 16) ? SDT_SYS386IGT : SDT_SYS386TGT,
1.489     fvdl     1890:                    (x == 3 || x == 4) ? SEL_UPL : SEL_KPL,
                   1891:                    GSEL(GCODE_SEL, SEL_KPL));
1.498     fvdl     1892:        }
1.257     thorpej  1893:
1.275     mycroft  1894:        /* new-style interrupt gate for syscalls */
1.618     yamt     1895:        idt_vec_reserve(128);
1.516     fvdl     1896:        setgate(&idt[128], &IDTVEC(syscall), 0, SDT_SYS386TGT, SEL_UPL,
1.489     fvdl     1897:            GSEL(GCODE_SEL, SEL_KPL));
1.333     christos 1898: #ifdef COMPAT_SVR4
1.618     yamt     1899:        idt_vec_reserve(0xd2);
1.516     fvdl     1900:        setgate(&idt[0xd2], &IDTVEC(svr4_fasttrap), 0, SDT_SYS386TGT,
1.489     fvdl     1901:            SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
1.333     christos 1902: #endif /* COMPAT_SVR4 */
1.264     mycroft  1903:
1.275     mycroft  1904:        setregion(&region, gdt, NGDT * sizeof(gdt[0]) - 1);
                   1905:        lgdt(&region);
1.484     fvdl     1906:
                   1907:        cpu_init_idt();
1.622     bouyer   1908: #else /* !XEN */
                   1909:        memset(xen_idt, 0, sizeof(trap_info_t) * MAX_XEN_IDT);
                   1910:        xen_idt_idx = 0;
                   1911:        for (x = 0; x < 32; x++) {
                   1912:                KASSERT(xen_idt_idx < MAX_XEN_IDT);
                   1913:                xen_idt[xen_idt_idx].vector = x;
1.640     cegger   1914:
                   1915:                switch (x) {
                   1916:                case 2:  /* NMI */
                   1917:                case 18: /* MCA */
                   1918:                        TI_SET_IF(&(xen_idt[xen_idt_idx]), 2);
                   1919:                        break;
                   1920:                case 3:
                   1921:                case 4:
                   1922:                        xen_idt[xen_idt_idx].flags = SEL_UPL;
                   1923:                        break;
                   1924:                default:
                   1925:                        xen_idt[xen_idt_idx].flags = SEL_XEN;
                   1926:                        break;
                   1927:                }
                   1928:
1.622     bouyer   1929:                xen_idt[xen_idt_idx].cs = GSEL(GCODE_SEL, SEL_KPL);
                   1930:                xen_idt[xen_idt_idx].address =
                   1931:                        (uint32_t)IDTVEC(exceptions)[x];
                   1932:                xen_idt_idx++;
                   1933:        }
                   1934:        KASSERT(xen_idt_idx < MAX_XEN_IDT);
                   1935:        xen_idt[xen_idt_idx].vector = 128;
                   1936:        xen_idt[xen_idt_idx].flags = SEL_UPL;
                   1937:        xen_idt[xen_idt_idx].cs = GSEL(GCODE_SEL, SEL_KPL);
                   1938:        xen_idt[xen_idt_idx].address = (uint32_t)&IDTVEC(syscall);
                   1939:        xen_idt_idx++;
                   1940: #ifdef COMPAT_SVR4
                   1941:        KASSERT(xen_idt_idx < MAX_XEN_IDT);
                   1942:        xen_idt[xen_idt_idx].vector = 0xd2;
                   1943:        xen_idt[xen_idt_idx].flags = SEL_UPL;
                   1944:        xen_idt[xen_idt_idx].cs = GSEL(GCODE_SEL, SEL_KPL);
                   1945:        xen_idt[xen_idt_idx].address = (uint32_t)&IDTVEC(svr4_fasttrap);
                   1946:        xen_idt_idx++;
                   1947: #endif /* COMPAT_SVR4 */
                   1948:        lldt(GSEL(GLDT_SEL, SEL_KPL));
                   1949:
                   1950:        XENPRINTF(("HYPERVISOR_set_trap_table %p\n", xen_idt));
                   1951:        if (HYPERVISOR_set_trap_table(xen_idt))
                   1952:                panic("HYPERVISOR_set_trap_table %p failed\n", xen_idt);
                   1953: #endif /* XEN */
1.264     mycroft  1954:
1.617     jmcneill 1955:        init386_ksyms();
1.308     tv       1956:
1.632     ad       1957: #if NMCA > 0
                   1958:        /* check for MCA bus, needed to be done before ISA stuff - if
                   1959:         * MCA is detected, ISA needs to use level triggered interrupts
                   1960:         * by default */
                   1961:        mca_busprobe();
                   1962: #endif
                   1963:
                   1964: #ifdef XEN
                   1965:        XENPRINTF(("events_default_setup\n"));
                   1966:        events_default_setup();
                   1967: #else
                   1968:        intr_default_setup();
                   1969: #endif
                   1970:
                   1971:        splraise(IPL_IPI);
                   1972:        x86_enable_intr();
                   1973:
1.522     ragge    1974: #ifdef DDB
1.190     mycroft  1975:        if (boothowto & RB_KDB)
                   1976:                Debugger();
1.377     ws       1977: #endif
                   1978: #ifdef IPKDB
                   1979:        ipkdb_init();
                   1980:        if (boothowto & RB_KDB)
                   1981:                ipkdb_connect(0);
1.190     mycroft  1982: #endif
                   1983: #ifdef KGDB
1.243     drochner 1984:        kgdb_port_init();
1.235     thorpej  1985:        if (boothowto & RB_KDB) {
                   1986:                kgdb_debug_init = 1;
1.242     drochner 1987:                kgdb_connect(1);
1.235     thorpej  1988:        }
1.384     jdolecek 1989: #endif
                   1990:
1.275     mycroft  1991:        if (physmem < btoc(2 * 1024 * 1024)) {
                   1992:                printf("warning: too little memory available; "
1.383     mycroft  1993:                       "have %lu bytes, want %lu bytes\n"
1.275     mycroft  1994:                       "running in degraded mode\n"
                   1995:                       "press a key to confirm\n\n",
1.383     mycroft  1996:                       ptoa(physmem), 2*1024*1024UL);
1.275     mycroft  1997:                cngetc();
                   1998:        }
1.1       cgd      1999: }
                   2000:
1.107     deraadt  2001: #ifdef COMPAT_NOMID
                   2002: static int
1.566     christos 2003: exec_nomid(struct lwp *l, struct exec_package *epp)
1.31      cgd      2004: {
1.59      mycroft  2005:        int error;
                   2006:        u_long midmag, magic;
                   2007:        u_short mid;
1.80      cgd      2008:        struct exec *execp = epp->ep_hdr;
1.31      cgd      2009:
1.80      cgd      2010:        /* check on validity of epp->ep_hdr performed by exec_out_makecmds */
                   2011:
                   2012:        midmag = ntohl(execp->a_midmag);
1.59      mycroft  2013:        mid = (midmag >> 16) & 0xffff;
                   2014:        magic = midmag & 0xffff;
                   2015:
                   2016:        if (magic == 0) {
1.80      cgd      2017:                magic = (execp->a_midmag & 0xffff);
1.59      mycroft  2018:                mid = MID_ZERO;
                   2019:        }
                   2020:
                   2021:        midmag = mid << 16 | magic;
                   2022:
                   2023:        switch (midmag) {
                   2024:        case (MID_ZERO << 16) | ZMAGIC:
                   2025:                /*
                   2026:                 * 386BSD's ZMAGIC format:
                   2027:                 */
1.566     christos 2028:                error = exec_aout_prep_oldzmagic(l, epp);
1.59      mycroft  2029:                break;
                   2030:
                   2031:        case (MID_ZERO << 16) | QMAGIC:
                   2032:                /*
                   2033:                 * BSDI's QMAGIC format:
                   2034:                 * same as new ZMAGIC format, but with different magic number
                   2035:                 */
1.566     christos 2036:                error = exec_aout_prep_zmagic(l, epp);
1.59      mycroft  2037:                break;
                   2038:
1.202     christos 2039:        case (MID_ZERO << 16) | NMAGIC:
                   2040:                /*
                   2041:                 * BSDI's NMAGIC format:
                   2042:                 * same as NMAGIC format, but with different magic number
                   2043:                 * and with text starting at 0.
                   2044:                 */
1.566     christos 2045:                error = exec_aout_prep_oldnmagic(l, epp);
1.202     christos 2046:                break;
                   2047:
                   2048:        case (MID_ZERO << 16) | OMAGIC:
                   2049:                /*
                   2050:                 * BSDI's OMAGIC format:
                   2051:                 * same as OMAGIC format, but with different magic number
                   2052:                 * and with text starting at 0.
                   2053:                 */
1.566     christos 2054:                error = exec_aout_prep_oldomagic(l, epp);
1.202     christos 2055:                break;
                   2056:
1.59      mycroft  2057:        default:
                   2058:                error = ENOEXEC;
                   2059:        }
                   2060:
                   2061:        return error;
1.107     deraadt  2062: }
1.31      cgd      2063: #endif
1.107     deraadt  2064:
                   2065: /*
                   2066:  * cpu_exec_aout_makecmds():
1.549     wiz      2067:  *     CPU-dependent a.out format hook for execve().
1.107     deraadt  2068:  *
                   2069:  * Determine of the given exec package refers to something which we
                   2070:  * understand and, if so, set up the vmcmds for it.
                   2071:  *
                   2072:  * On the i386, old (386bsd) ZMAGIC binaries and BSDI QMAGIC binaries
                   2073:  * if COMPAT_NOMID is given as a kernel option.
                   2074:  */
                   2075: int
1.566     christos 2076: cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp)
1.107     deraadt  2077: {
                   2078:        int error = ENOEXEC;
                   2079:
                   2080: #ifdef COMPAT_NOMID
1.566     christos 2081:        if ((error = exec_nomid(l, epp)) == 0)
1.107     deraadt  2082:                return error;
1.581     thorpej  2083: #else
                   2084:        (void) l;
                   2085:        (void) epp;
1.107     deraadt  2086: #endif /* ! COMPAT_NOMID */
                   2087:
                   2088:        return error;
1.31      cgd      2089: }
1.84      cgd      2090:
1.484     fvdl     2091: #include <dev/ic/mc146818reg.h>                /* for NVRAM POST */
                   2092: #include <i386/isa/nvram.h>            /* for NVRAM POST */
                   2093:
1.149     mycroft  2094: void
                   2095: cpu_reset()
                   2096: {
1.622     bouyer   2097: #ifdef XEN
                   2098:        HYPERVISOR_reboot();
                   2099:        for (;;);
                   2100: #else /* XEN */
1.555     mycroft  2101:        struct region_descriptor region;
1.149     mycroft  2102:
1.608     ad       2103:        x86_disable_intr();
1.587     jmcneill 2104: #ifdef XBOX
                   2105:        if (arch_i386_is_xbox) {
1.591     jmcneill 2106:                xbox_reboot();
1.587     jmcneill 2107:                for (;;);
                   2108:        }
                   2109: #endif
                   2110:
1.227     mycroft  2111:        /*
1.484     fvdl     2112:         * Ensure the NVRAM reset byte contains something vaguely sane.
                   2113:         */
                   2114:
                   2115:        outb(IO_RTC, NVRAM_RESET);
                   2116:        outb(IO_RTC+1, NVRAM_RESET_RST);
                   2117:
                   2118:        /*
1.564     dyoung   2119:         * Reset AMD Geode SC1100.
                   2120:         *
1.565     simonb   2121:         * 1) Write PCI Configuration Address Register (0xcf8) to
                   2122:         *    select Function 0, Register 0x44: Bridge Configuration,
                   2123:         *    GPIO and LPC Configuration Register Space, Reset
                   2124:         *    Control Register.
1.564     dyoung   2125:         *
1.565     simonb   2126:         * 2) Write 0xf to PCI Configuration Data Register (0xcfc)
                   2127:         *    to reset IDE controller, IDE bus, and PCI bus, and
                   2128:         *    to trigger a system-wide reset.
1.564     dyoung   2129:         *
                   2130:         * See AMD Geode SC1100 Processor Data Book, Revision 2.0,
                   2131:         * sections 6.3.1, 6.3.2, and 6.4.1.
                   2132:         */
                   2133:        if (cpu_info_primary.ci_signature == 0x540) {
1.608     ad       2134:                outl(0xcf8, 0x80009044);
1.564     dyoung   2135:                outl(0xcfc, 0xf);
1.565     simonb   2136:        }
1.564     dyoung   2137:
                   2138:        /*
1.227     mycroft  2139:         * The keyboard controller has 4 random output pins, one of which is
                   2140:         * connected to the RESET pin on the CPU in many PCs.  We tell the
                   2141:         * keyboard controller to pulse this line a couple of times.
                   2142:         */
1.273     drochner 2143:        outb(IO_KBD + KBCMDP, KBC_PULSE0);
1.226     mycroft  2144:        delay(100000);
1.273     drochner 2145:        outb(IO_KBD + KBCMDP, KBC_PULSE0);
1.226     mycroft  2146:        delay(100000);
1.149     mycroft  2147:
                   2148:        /*
1.224     mycroft  2149:         * Try to cause a triple fault and watchdog reset by making the IDT
                   2150:         * invalid and causing a fault.
1.149     mycroft  2151:         */
1.600     christos 2152:        memset((void *)idt, 0, NIDT * sizeof(idt[0]));
1.555     mycroft  2153:        setregion(&region, idt, NIDT * sizeof(idt[0]) - 1);
1.565     simonb   2154:        lidt(&region);
1.608     ad       2155:        breakpoint();
1.149     mycroft  2156:
1.224     mycroft  2157: #if 0
1.149     mycroft  2158:        /*
                   2159:         * Try to cause a triple fault and watchdog reset by unmapping the
1.224     mycroft  2160:         * entire address space and doing a TLB flush.
1.149     mycroft  2161:         */
1.600     christos 2162:        memset((void *)PTD, 0, PAGE_SIZE);
1.484     fvdl     2163:        tlbflush();
1.224     mycroft  2164: #endif
1.149     mycroft  2165:
                   2166:        for (;;);
1.622     bouyer   2167: #endif /* XEN */
1.45      cgd      2168: }
1.484     fvdl     2169:
1.499     jdolecek 2170: void
1.551     junyoung 2171: cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags)
1.508     thorpej  2172: {
                   2173:        const struct trapframe *tf = l->l_md.md_regs;
                   2174:        __greg_t *gr = mcp->__gregs;
1.519     nathanw  2175:        __greg_t ras_eip;
1.508     thorpej  2176:
                   2177:        /* Save register context. */
                   2178: #ifdef VM86
                   2179:        if (tf->tf_eflags & PSL_VM) {
                   2180:                gr[_REG_GS]  = tf->tf_vm86_gs;
                   2181:                gr[_REG_FS]  = tf->tf_vm86_fs;
                   2182:                gr[_REG_ES]  = tf->tf_vm86_es;
                   2183:                gr[_REG_DS]  = tf->tf_vm86_ds;
                   2184:                gr[_REG_EFL] = get_vflags(l);
                   2185:        } else
                   2186: #endif
                   2187:        {
                   2188:                gr[_REG_GS]  = tf->tf_gs;
                   2189:                gr[_REG_FS]  = tf->tf_fs;
                   2190:                gr[_REG_ES]  = tf->tf_es;
                   2191:                gr[_REG_DS]  = tf->tf_ds;
                   2192:                gr[_REG_EFL] = tf->tf_eflags;
                   2193:        }
                   2194:        gr[_REG_EDI]    = tf->tf_edi;
                   2195:        gr[_REG_ESI]    = tf->tf_esi;
                   2196:        gr[_REG_EBP]    = tf->tf_ebp;
                   2197:        gr[_REG_EBX]    = tf->tf_ebx;
                   2198:        gr[_REG_EDX]    = tf->tf_edx;
                   2199:        gr[_REG_ECX]    = tf->tf_ecx;
                   2200:        gr[_REG_EAX]    = tf->tf_eax;
                   2201:        gr[_REG_EIP]    = tf->tf_eip;
                   2202:        gr[_REG_CS]     = tf->tf_cs;
                   2203:        gr[_REG_ESP]    = tf->tf_esp;
                   2204:        gr[_REG_UESP]   = tf->tf_esp;
                   2205:        gr[_REG_SS]     = tf->tf_ss;
                   2206:        gr[_REG_TRAPNO] = tf->tf_trapno;
                   2207:        gr[_REG_ERR]    = tf->tf_err;
1.519     nathanw  2208:
                   2209:        if ((ras_eip = (__greg_t)ras_lookup(l->l_proc,
1.600     christos 2210:            (void *) gr[_REG_EIP])) != -1)
1.519     nathanw  2211:                gr[_REG_EIP] = ras_eip;
                   2212:
1.508     thorpej  2213:        *flags |= _UC_CPU;
                   2214:
                   2215:        /* Save floating point register context, if any. */
1.548     yamt     2216:        if ((l->l_md.md_flags & MDL_USEDFPU) != 0) {
1.508     thorpej  2217: #if NNPX > 0
                   2218:                /*
                   2219:                 * If this process is the current FP owner, dump its
                   2220:                 * context to the PCB first.
                   2221:                 */
                   2222:                if (l->l_addr->u_pcb.pcb_fpcpu) {
1.624     joerg    2223:                        npxsave_lwp(l, true);
1.508     thorpej  2224:                }
                   2225: #endif
                   2226:                if (i386_use_fxsave) {
                   2227:                        memcpy(&mcp->__fpregs.__fp_reg_set.__fp_xmm_state.__fp_xmm,
                   2228:                            &l->l_addr->u_pcb.pcb_savefpu.sv_xmm,
                   2229:                            sizeof (mcp->__fpregs.__fp_reg_set.__fp_xmm_state.__fp_xmm));
                   2230:                        *flags |= _UC_FXSAVE;
                   2231:                } else {
                   2232:                        memcpy(&mcp->__fpregs.__fp_reg_set.__fpchip_state.__fp_state,
                   2233:                            &l->l_addr->u_pcb.pcb_savefpu.sv_87,
                   2234:                            sizeof (mcp->__fpregs.__fp_reg_set.__fpchip_state.__fp_state));
                   2235:                }
                   2236: #if 0
                   2237:                /* Apparently nothing ever touches this. */
                   2238:                ucp->mcp.mc_fp.fp_emcsts = l->l_addr->u_pcb.pcb_saveemc;
                   2239: #endif
                   2240:                *flags |= _UC_FPU;
                   2241:        }
                   2242: }
                   2243:
                   2244: int
1.551     junyoung 2245: cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
1.508     thorpej  2246: {
                   2247:        struct trapframe *tf = l->l_md.md_regs;
1.584     pooka    2248:        const __greg_t *gr = mcp->__gregs;
1.595     ad       2249:        struct proc *p = l->l_proc;
1.508     thorpej  2250:
                   2251:        /* Restore register context, if any. */
                   2252:        if ((flags & _UC_CPU) != 0) {
                   2253: #ifdef VM86
1.535     drochner 2254:                if (gr[_REG_EFL] & PSL_VM) {
1.508     thorpej  2255:                        tf->tf_vm86_gs = gr[_REG_GS];
                   2256:                        tf->tf_vm86_fs = gr[_REG_FS];
                   2257:                        tf->tf_vm86_es = gr[_REG_ES];
                   2258:                        tf->tf_vm86_ds = gr[_REG_DS];
                   2259:                        set_vflags(l, gr[_REG_EFL]);
1.534     christos 2260:                        if (flags & _UC_VM) {
1.542     junyoung 2261:                                void syscall_vm86(struct trapframe *);
1.534     christos 2262:                                l->l_proc->p_md.md_syscall = syscall_vm86;
                   2263:                        }
1.508     thorpej  2264:                } else
                   2265: #endif
                   2266:                {
                   2267:                        /*
                   2268:                         * Check for security violations.  If we're returning
                   2269:                         * to protected mode, the CPU will validate the segment
                   2270:                         * registers automatically and generate a trap on
                   2271:                         * violations.  We handle the trap, rather than doing
                   2272:                         * all of the checking here.
                   2273:                         */
1.534     christos 2274:                        if (((gr[_REG_EFL] ^ tf->tf_eflags) & PSL_USERSTATIC) ||
                   2275:                            !USERMODE(gr[_REG_CS], gr[_REG_EFL])) {
                   2276:                                printf("cpu_setmcontext error: uc EFL: 0x%08x"
1.535     drochner 2277:                                    " tf EFL: 0x%08x uc CS: 0x%x\n",
1.508     thorpej  2278:                                    gr[_REG_EFL], tf->tf_eflags, gr[_REG_CS]);
                   2279:                                return (EINVAL);
                   2280:                        }
                   2281:                        tf->tf_gs = gr[_REG_GS];
                   2282:                        tf->tf_fs = gr[_REG_FS];
                   2283:                        tf->tf_es = gr[_REG_ES];
                   2284:                        tf->tf_ds = gr[_REG_DS];
                   2285:                        /* Only change the user-alterable part of eflags */
                   2286:                        tf->tf_eflags &= ~PSL_USER;
                   2287:                        tf->tf_eflags |= (gr[_REG_EFL] & PSL_USER);
                   2288:                }
                   2289:                tf->tf_edi    = gr[_REG_EDI];
                   2290:                tf->tf_esi    = gr[_REG_ESI];
                   2291:                tf->tf_ebp    = gr[_REG_EBP];
                   2292:                tf->tf_ebx    = gr[_REG_EBX];
                   2293:                tf->tf_edx    = gr[_REG_EDX];
                   2294:                tf->tf_ecx    = gr[_REG_ECX];
                   2295:                tf->tf_eax    = gr[_REG_EAX];
                   2296:                tf->tf_eip    = gr[_REG_EIP];
                   2297:                tf->tf_cs     = gr[_REG_CS];
                   2298:                tf->tf_esp    = gr[_REG_UESP];
                   2299:                tf->tf_ss     = gr[_REG_SS];
                   2300:        }
                   2301:
1.647     ad       2302: #if NNPX > 0
                   2303:        /*
                   2304:         * If we were using the FPU, forget that we were.
                   2305:         */
                   2306:        if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
                   2307:                npxsave_lwp(l, false);
                   2308: #endif
                   2309:
1.508     thorpej  2310:        /* Restore floating point register context, if any. */
                   2311:        if ((flags & _UC_FPU) != 0) {
                   2312:                if (flags & _UC_FXSAVE) {
                   2313:                        if (i386_use_fxsave) {
                   2314:                                memcpy(
                   2315:                                        &l->l_addr->u_pcb.pcb_savefpu.sv_xmm,
                   2316:                                        &mcp->__fpregs.__fp_reg_set.__fp_xmm_state.__fp_xmm,
                   2317:                                        sizeof (&l->l_addr->u_pcb.pcb_savefpu.sv_xmm));
                   2318:                        } else {
                   2319:                                /* This is a weird corner case */
                   2320:                                process_xmm_to_s87((struct savexmm *)
                   2321:                                    &mcp->__fpregs.__fp_reg_set.__fp_xmm_state.__fp_xmm,
                   2322:                                    &l->l_addr->u_pcb.pcb_savefpu.sv_87);
                   2323:                        }
                   2324:                } else {
                   2325:                        if (i386_use_fxsave) {
                   2326:                                process_s87_to_xmm((struct save87 *)
                   2327:                                    &mcp->__fpregs.__fp_reg_set.__fpchip_state.__fp_state,
                   2328:                                    &l->l_addr->u_pcb.pcb_savefpu.sv_xmm);
                   2329:                        } else {
                   2330:                                memcpy(&l->l_addr->u_pcb.pcb_savefpu.sv_87,
                   2331:                                    &mcp->__fpregs.__fp_reg_set.__fpchip_state.__fp_state,
                   2332:                                    sizeof (l->l_addr->u_pcb.pcb_savefpu.sv_87));
                   2333:                        }
                   2334:                }
1.548     yamt     2335:                l->l_md.md_flags |= MDL_USEDFPU;
1.508     thorpej  2336:        }
1.629     ad       2337:        mutex_enter(p->p_lock);
1.534     christos 2338:        if (flags & _UC_SETSTACK)
1.595     ad       2339:                l->l_sigstk.ss_flags |= SS_ONSTACK;
1.534     christos 2340:        if (flags & _UC_CLRSTACK)
1.595     ad       2341:                l->l_sigstk.ss_flags &= ~SS_ONSTACK;
1.629     ad       2342:        mutex_exit(p->p_lock);
1.508     thorpej  2343:        return (0);
                   2344: }
                   2345:
                   2346: void
1.499     jdolecek 2347: cpu_initclocks()
1.484     fvdl     2348: {
1.574     kardel   2349:
1.484     fvdl     2350:        (*initclock_func)();
                   2351: }

CVSweb <webmaster@jp.NetBSD.org>