[BACK]Return to machdep.c CVS log [TXT][DIR] Up to [local] / sys / arch / amd64 / amd64

Annotation of sys/arch/amd64/amd64/machdep.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: machdep.c,v 1.60 2007/08/02 16:40:27 deraadt Exp $    */
                      2: /*     $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
                     10:  * Simulation Facility, NASA Ames Research Center.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *     This product includes software developed by the NetBSD
                     23:  *     Foundation, Inc. and its contributors.
                     24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     25:  *    contributors may be used to endorse or promote products derived
                     26:  *    from this software without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     38:  * POSSIBILITY OF SUCH DAMAGE.
                     39:  */
                     40:
                     41: /*-
                     42:  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
                     43:  * All rights reserved.
                     44:  *
                     45:  * This code is derived from software contributed to Berkeley by
                     46:  * William Jolitz.
                     47:  *
                     48:  * Redistribution and use in source and binary forms, with or without
                     49:  * modification, are permitted provided that the following conditions
                     50:  * are met:
                     51:  * 1. Redistributions of source code must retain the above copyright
                     52:  *    notice, this list of conditions and the following disclaimer.
                     53:  * 2. Redistributions in binary form must reproduce the above copyright
                     54:  *    notice, this list of conditions and the following disclaimer in the
                     55:  *    documentation and/or other materials provided with the distribution.
                     56:  * 3. Neither the name of the University nor the names of its contributors
                     57:  *    may be used to endorse or promote products derived from this software
                     58:  *    without specific prior written permission.
                     59:  *
                     60:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     61:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     62:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     63:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     64:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     65:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     66:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     67:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     68:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     69:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     70:  * SUCH DAMAGE.
                     71:  *
                     72:  *     @(#)machdep.c   7.4 (Berkeley) 6/3/91
                     73:  */
                     74:
                     75: #include <sys/param.h>
                     76: #include <sys/systm.h>
                     77: #include <sys/signal.h>
                     78: #include <sys/signalvar.h>
                     79: #include <sys/kernel.h>
                     80: #include <sys/proc.h>
                     81: #include <sys/user.h>
                     82: #include <sys/exec.h>
                     83: #include <sys/buf.h>
                     84: #include <sys/reboot.h>
                     85: #include <sys/conf.h>
                     86: #include <sys/file.h>
                     87: #include <sys/malloc.h>
                     88: #include <sys/mbuf.h>
                     89: #include <sys/msgbuf.h>
                     90: #include <sys/mount.h>
                     91: #include <sys/vnode.h>
                     92: #include <sys/extent.h>
                     93: #include <sys/core.h>
                     94: #include <sys/kcore.h>
                     95: #include <sys/syscallargs.h>
                     96:
                     97: #ifdef SYSVMSG
                     98: #include <sys/msg.h>
                     99: #endif
                    100:
                    101: #ifdef KGDB
                    102: #include <sys/kgdb.h>
                    103: #endif
                    104:
                    105: #include <dev/cons.h>
                    106: #include <stand/boot/bootarg.h>
                    107:
                    108: #include <uvm/uvm_extern.h>
                    109: #include <uvm/uvm_page.h>
                    110:
                    111: #include <sys/sysctl.h>
                    112:
                    113: #include <machine/cpu.h>
                    114: #include <machine/cpufunc.h>
                    115: #include <machine/gdt.h>
                    116: #include <machine/pio.h>
                    117: #include <machine/psl.h>
                    118: #include <machine/reg.h>
                    119: #include <machine/specialreg.h>
                    120: #include <machine/fpu.h>
                    121: #include <machine/mtrr.h>
                    122: #include <machine/biosvar.h>
                    123: #include <machine/mpbiosvar.h>
                    124: #include <machine/reg.h>
                    125: #include <machine/kcore.h>
                    126:
                    127: #include <dev/isa/isareg.h>
                    128: #include <machine/isa_machdep.h>
                    129: #include <dev/ic/i8042reg.h>
                    130: #include <amd64/isa/nvram.h>
                    131:
                    132: #ifdef DDB
                    133: #include <machine/db_machdep.h>
                    134: #include <ddb/db_extern.h>
                    135: #endif
                    136:
                    137: #include "isa.h"
                    138: #include "isadma.h"
                    139: #include "ksyms.h"
                    140:
                    141: #include "acpi.h"
                    142: #if NACPI > 0
                    143: #include <dev/acpi/acpivar.h>
                    144: #endif
                    145:
                    146:
                    147: /* the following is used externally (sysctl_hw) */
                    148: char machine[] = MACHINE;
                    149:
                    150: /* the following is used externally for concurrent handlers */
                    151: int setperf_prio = 0;
                    152:
                    153: #ifdef CPURESET_DELAY
                    154: int    cpureset_delay = CPURESET_DELAY;
                    155: #else
                    156: int     cpureset_delay = 2000; /* default to 2s */
                    157: #endif
                    158:
                    159: int    physmem;
                    160: u_int64_t      dumpmem_low;
                    161: u_int64_t      dumpmem_high;
                    162: extern int     boothowto;
                    163: int    cpu_class;
                    164:
                    165: char   *ssym = NULL;
                    166: vaddr_t kern_end;
                    167:
                    168: vaddr_t        msgbuf_vaddr;
                    169: paddr_t msgbuf_paddr;
                    170:
                    171: vaddr_t        idt_vaddr;
                    172: paddr_t        idt_paddr;
                    173:
                    174: vaddr_t lo32_vaddr;
                    175: paddr_t lo32_paddr;
                    176:
                    177: int kbd_reset;
                    178:
                    179: struct vm_map *exec_map = NULL;
                    180: struct vm_map *phys_map = NULL;
                    181:
                    182: #ifndef BUFCACHEPERCENT
                    183: #define BUFCACHEPERCENT 10
                    184: #endif
                    185:
                    186: #ifdef BUFPAGES
                    187: int    bufpages = BUFPAGES;
                    188: #else
                    189: int    bufpages = 0;
                    190: #endif
                    191: int bufcachepercent = BUFCACHEPERCENT;
                    192:
                    193: #ifdef DEBUG
                    194: int sigdebug = 0;
                    195: pid_t sigpid = 0;
                    196: #define SDB_FOLLOW      0x01
                    197: #endif
                    198:
                    199: extern paddr_t avail_start, avail_end;
                    200:
                    201: void (*delay_func)(int) = i8254_delay;
                    202: void (*initclock_func)(void) = i8254_initclocks;
                    203:
                    204: struct mtrr_funcs *mtrr_funcs;
                    205:
                    206: /*
                    207:  * Format of boot information passed to us by 32-bit /boot
                    208:  */
                    209: typedef struct _boot_args32 {
                    210:        int     ba_type;
                    211:        int     ba_size;
                    212:        int     ba_nextX;       /* a ptr in 32-bit world, but not here */
                    213:        char    ba_arg[1];
                    214: } bootarg32_t;
                    215:
                    216: #define BOOTARGC_MAX   NBPG    /* one page */
                    217:
                    218: #ifdef NFSCLIENT
                    219: bios_bootmac_t *bios_bootmac;
                    220: #endif
                    221:
                    222: /* locore copies the arguments from /boot to here for us */
                    223: char bootinfo[BOOTARGC_MAX];
                    224: int bootinfo_size = BOOTARGC_MAX;
                    225:
                    226: void getbootinfo(char *, int);
                    227:
                    228: /* Data passed to us by /boot, filled in by getbootinfo() */
                    229: #if NAPM > 0 || defined(DEBUG)
                    230: bios_apminfo_t *apm;
                    231: #endif
                    232: #if NPCI > 0
                    233: bios_pciinfo_t *bios_pciinfo;
                    234: #endif
                    235: bios_diskinfo_t        *bios_diskinfo;
                    236: bios_memmap_t  *bios_memmap;
                    237: u_int32_t      bios_cksumlen;
                    238:
                    239: /*
                    240:  * Size of memory segments, before any memory is stolen.
                    241:  */
                    242: phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
                    243: int    mem_cluster_cnt;
                    244:
                    245: vaddr_t        allocsys(vaddr_t);
                    246: void   setup_buffers(void);
                    247: int    cpu_dump(void);
                    248: int    cpu_dumpsize(void);
                    249: u_long cpu_dump_mempagecnt(void);
                    250: void   dumpsys(void);
                    251: void   init_x86_64(paddr_t);
                    252:
                    253: #ifdef KGDB
                    254: #ifndef KGDB_DEVNAME
                    255: #define KGDB_DEVNAME   "com"
                    256: #endif /* KGDB_DEVNAME */
                    257: char kgdb_devname[] = KGDB_DEVNAME;
                    258: #if NCOM > 0
                    259: #ifndef KGDBADDR
                    260: #define KGDBADDR       0x3f8
                    261: #endif /* KGDBADDR */
                    262: int comkgdbaddr = KGDBADDR;
                    263: #ifndef KGDBRATE
                    264: #define KGDBRATE       TTYDEF_SPEED
                    265: #endif /* KGDBRATE */
                    266: int comkgdbrate = KGDBRATE;
                    267: #ifndef KGDBMODE
                    268: #define KGDBMODE       ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8)
                    269: #endif /* KGDBMODE */
                    270: int comkgdbmode = KGDBMODE;
                    271: #endif /* NCOM */
                    272: void   kgdb_port_init(void);
                    273: #endif /* KGDB */
                    274:
                    275: #ifdef APERTURE
                    276: #ifdef INSECURE
                    277: int allowaperture = 1;
                    278: #else
                    279: int allowaperture = 0;
                    280: #endif
                    281: #endif
                    282:
                    283: /*
                    284:  * Machine-dependent startup code
                    285:  */
                    286: void
                    287: cpu_startup(void)
                    288: {
                    289:        vaddr_t v;
                    290:        vsize_t sz;
                    291:        vaddr_t minaddr, maxaddr;
                    292:
                    293:        msgbuf_vaddr = PMAP_DIRECT_MAP(msgbuf_paddr);
                    294:        initmsgbuf((caddr_t)msgbuf_vaddr, round_page(MSGBUFSIZE));
                    295:
                    296:        printf("%s", version);
                    297:
                    298:        printf("real mem = %u (%uMB)\n", ctob(physmem),
                    299:            ctob(physmem)/1024/1024);
                    300:
                    301:        if (physmem >= btoc(1ULL << 32)) {
                    302:                extern int amdgart_enable;
                    303:
                    304:                amdgart_enable = 1;
                    305:        }
                    306:
                    307:        /*
                    308:         * Find out how much space we need, allocate it,
                    309:         * and then give everything true virtual addresses.
                    310:         */
                    311:        sz = allocsys(0);
                    312:        if ((v = uvm_km_zalloc(kernel_map, round_page(sz))) == 0)
                    313:                panic("startup: no room for tables");
                    314:        if (allocsys(v) - v != sz)
                    315:                panic("startup: table size inconsistency");
                    316:
                    317:        setup_buffers();
                    318:
                    319:        /*
                    320:         * Allocate a submap for exec arguments.  This map effectively
                    321:         * limits the number of processes exec'ing at any time.
                    322:         */
                    323:        minaddr = vm_map_min(kernel_map);
                    324:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
                    325:                                   16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
                    326:
                    327:        /*
                    328:         * Allocate a submap for physio
                    329:         */
                    330:        minaddr = vm_map_min(kernel_map);
                    331:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
                    332:                                   VM_PHYS_SIZE, 0, FALSE, NULL);
                    333:
                    334:        printf("avail mem = %lu (%luMB)\n", ptoa(uvmexp.free),
                    335:            ptoa(uvmexp.free)/1024/1024);
                    336:
                    337:        bufinit();
                    338:
                    339:        if (boothowto & RB_CONFIG) {
                    340: #ifdef BOOT_CONFIG
                    341:                user_config();
                    342: #else
                    343:                printf("kernel does not support - c; continuing..\n");
                    344: #endif
                    345:        }
                    346:
                    347:        /* Safe for i/o port / memory space allocation to use malloc now. */
                    348:        x86_bus_space_mallocok();
                    349: }
                    350:
                    351: /*
                    352:  * Allocate space for system data structures.  We are given
                    353:  * a starting virtual address and we return a final virtual
                    354:  * address; along the way we set each data structure pointer.
                    355:  *
                    356:  * We call allocsys() with 0 to find out how much space we want,
                    357:  * allocate that much and fill it with zeroes, and then call
                    358:  * allocsys() again with the correct base virtual address.
                    359:  */
                    360: vaddr_t
                    361: allocsys(vaddr_t v)
                    362: {
                    363:
                    364: #define        valloc(name, type, num) \
                    365:            v = (vaddr_t)(((name) = (type *)v) + (num))
                    366:
                    367: #ifdef SYSVMSG
                    368:        valloc(msgpool, char, msginfo.msgmax);
                    369:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
                    370:        valloc(msghdrs, struct msg, msginfo.msgtql);
                    371:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
                    372: #endif
                    373:
                    374:        return v;
                    375: }
                    376:
                    377: void
                    378: setup_buffers()
                    379: {
                    380:        /*
                    381:         * Determine how many buffers to allocate.
                    382:         * We allocate bufcachepercent% of memory for buffer space.
                    383:         */
                    384:        if (bufpages == 0)
                    385:                bufpages = physmem * bufcachepercent / 100;
                    386:
                    387:        /* Restrict to at most 25% filled kvm */
                    388:        if (bufpages >
                    389:            (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
                    390:                bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
                    391:                    PAGE_SIZE / 4;
                    392: }
                    393:
                    394: /*
                    395:  * Set up proc0's TSS and LDT.
                    396:  */
                    397: void
                    398: x86_64_proc0_tss_ldt_init(void)
                    399: {
                    400:        struct pcb *pcb;
                    401:        int x;
                    402:
                    403:        gdt_init();
                    404:
                    405:        cpu_info_primary.ci_curpcb = pcb = &proc0.p_addr->u_pcb;
                    406:
                    407:        pcb->pcb_flags = 0;
                    408:        pcb->pcb_tss.tss_iobase =
                    409:            (u_int16_t)((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss);
                    410:        for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++)
                    411:                pcb->pcb_iomap[x] = 0xffffffff;
                    412:
                    413:        pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel =
                    414:            GSYSSEL(GLDT_SEL, SEL_KPL);
                    415:        pcb->pcb_cr0 = rcr0();
                    416:        pcb->pcb_tss.tss_rsp0 = (u_int64_t)proc0.p_addr + USPACE - 16;
                    417:        pcb->pcb_tss.tss_ist[0] = (u_int64_t)proc0.p_addr + PAGE_SIZE;
                    418:        proc0.p_md.md_regs = (struct trapframe *)pcb->pcb_tss.tss_rsp0 - 1;
                    419:        proc0.p_md.md_tss_sel = tss_alloc(pcb);
                    420:
                    421:        ltr(proc0.p_md.md_tss_sel);
                    422:        lldt(pcb->pcb_ldt_sel);
                    423: }
                    424:
                    425: /*
                    426:  * Set up TSS and LDT for a new PCB.
                    427:  */
                    428:
                    429: #ifdef MULTIPROCESSOR
                    430: void
                    431: x86_64_init_pcb_tss_ldt(struct cpu_info *ci)
                    432: {
                    433:        int x;
                    434:        struct pcb *pcb = ci->ci_idle_pcb;
                    435:
                    436:        pcb->pcb_tss.tss_iobase =
                    437:            (u_int16_t)((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss);
                    438:        for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++)
                    439:                pcb->pcb_iomap[x] = 0xffffffff;
                    440:
                    441:        /* XXXfvdl pmap_kernel not needed */
                    442:        pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel =
                    443:            GSYSSEL(GLDT_SEL, SEL_KPL);
                    444:        pcb->pcb_cr0 = rcr0();
                    445:
                    446:         ci->ci_idle_tss_sel = tss_alloc(pcb);
                    447: }
                    448: #endif /* MULTIPROCESSOR */
                    449:
                    450: bios_diskinfo_t *
                    451: bios_getdiskinfo(dev_t dev)
                    452: {
                    453:        bios_diskinfo_t *pdi;
                    454:
                    455:        if (bios_diskinfo == NULL)
                    456:                return NULL;
                    457:
                    458:        for (pdi = bios_diskinfo; pdi->bios_number != -1; pdi++) {
                    459:                if ((dev & B_MAGICMASK) == B_DEVMAGIC) { /* search by bootdev */
                    460:                        if (pdi->bsd_dev == dev)
                    461:                                break;
                    462:                } else {
                    463:                        if (pdi->bios_number == dev)
                    464:                                break;
                    465:                }
                    466:        }
                    467:
                    468:        if (pdi->bios_number == -1)
                    469:                return NULL;
                    470:        else
                    471:                return pdi;
                    472: }
                    473:
                    474: int
                    475: bios_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
                    476:     size_t newlen, struct proc *p)
                    477: {
                    478:        bios_diskinfo_t *pdi;
                    479:        extern dev_t bootdev;
                    480:        int biosdev;
                    481:
                    482:        /* all sysctl names at this level except diskinfo are terminal */
                    483:        if (namelen != 1 && name[0] != BIOS_DISKINFO)
                    484:                return (ENOTDIR);              /* overloaded */
                    485:
                    486:        if (!(bootapiver & BAPIV_VECTOR))
                    487:                return EOPNOTSUPP;
                    488:
                    489:        switch (name[0]) {
                    490:        case BIOS_DEV:
                    491:                if ((pdi = bios_getdiskinfo(bootdev)) == NULL)
                    492:                        return ENXIO;
                    493:                biosdev = pdi->bios_number;
                    494:                return sysctl_rdint(oldp, oldlenp, newp, biosdev);
                    495:        case BIOS_DISKINFO:
                    496:                if (namelen != 2)
                    497:                        return ENOTDIR;
                    498:                if ((pdi = bios_getdiskinfo(name[1])) == NULL)
                    499:                        return ENXIO;
                    500:                return sysctl_rdstruct(oldp, oldlenp, newp, pdi, sizeof(*pdi));
                    501:        case BIOS_CKSUMLEN:
                    502:                return sysctl_rdint(oldp, oldlenp, newp, bios_cksumlen);
                    503:        default:
                    504:                return EOPNOTSUPP;
                    505:        }
                    506:        /* NOTREACHED */
                    507: }
                    508:
                    509: /*
                    510:  * machine dependent system variables.
                    511:  */
                    512: int
                    513: cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
                    514:     size_t newlen, struct proc *p)
                    515: {
                    516:        dev_t consdev;
                    517:        dev_t dev;
                    518:
                    519:        switch (name[0]) {
                    520:        case CPU_CONSDEV:
                    521:                if (namelen != 1)
                    522:                        return (ENOTDIR);               /* overloaded */
                    523:                if (cn_tab != NULL)
                    524:                        consdev = cn_tab->cn_dev;
                    525:                else
                    526:                        consdev = NODEV;
                    527:                return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
                    528:                    sizeof consdev));
                    529:        case CPU_CHR2BLK:
                    530:                if (namelen != 2)
                    531:                        return (ENOTDIR);               /* overloaded */
                    532:                dev = chrtoblk((dev_t)name[1]);
                    533:                return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev));
                    534:        case CPU_BIOS:
                    535:                return bios_sysctl(name + 1, namelen - 1, oldp, oldlenp,
                    536:                    newp, newlen, p);
                    537:        case CPU_CPUVENDOR:
                    538:                return (sysctl_rdstring(oldp, oldlenp, newp, cpu_vendor));
                    539:        case CPU_CPUFEATURE:
                    540:                return (sysctl_rdint(oldp, oldlenp, newp, cpu_feature));
                    541:        case CPU_KBDRESET:
                    542:                if (securelevel > 0)
                    543:                        return (sysctl_rdint(oldp, oldlenp, newp,
                    544:                            kbd_reset));
                    545:                else
                    546:                        return (sysctl_int(oldp, oldlenp, newp, newlen,
                    547:                            &kbd_reset));
                    548:        case CPU_ALLOWAPERTURE:
                    549:                if (namelen != 1)
                    550:                        return (ENOTDIR);               /* overloaded */
                    551: #ifdef APERTURE
                    552:                if (securelevel > 0)
                    553:                        return (sysctl_int_lower(oldp, oldlenp, newp, newlen,
                    554:                            &allowaperture));
                    555:                else
                    556:                        return (sysctl_int(oldp, oldlenp, newp, newlen,
                    557:                            &allowaperture));
                    558: #else
                    559:                return (sysctl_rdint(oldp, oldlenp, newp, 0));
                    560: #endif
                    561:        default:
                    562:                return (EOPNOTSUPP);
                    563:        }
                    564:        /* NOTREACHED */
                    565: }
                    566:
                    567: /*
                    568:  * Send an interrupt to process.
                    569:  *
                    570:  * Stack is set up to allow sigcode stored
                    571:  * in u. to call routine, followed by kcall
                    572:  * to sigreturn routine below.  After sigreturn
                    573:  * resets the signal mask, the stack, and the
                    574:  * frame pointer, it returns to the user
                    575:  * specified pc, psl.
                    576:  */
                    577: void
                    578: sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
                    579:     union sigval val)
                    580: {
                    581:        struct proc *p = curproc;
                    582:        struct trapframe *tf = p->p_md.md_regs;
                    583:        struct sigacts * psp = p->p_sigacts;
                    584:        struct sigcontext ksc;
                    585:        siginfo_t ksi;
                    586:        register_t sp, scp, sip;
                    587:        u_long sss;
                    588:
                    589: #ifdef DEBUG
                    590:        if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
                    591:                printf("sendsig: %s[%d] sig %d catcher %p\n",
                    592:                    p->p_comm, p->p_pid, sig, catcher);
                    593: #endif
                    594:
                    595:        bcopy(tf, &ksc, sizeof(*tf));
                    596:        ksc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
                    597:        ksc.sc_mask = mask;
                    598:        ksc.sc_fpstate = NULL;
                    599:
                    600:        /* Allocate space for the signal handler context. */
                    601:        if ((psp->ps_flags & SAS_ALTSTACK) && !ksc.sc_onstack &&
                    602:            (psp->ps_sigonstack & sigmask(sig))) {
                    603:                sp = (register_t)psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size;
                    604:                psp->ps_sigstk.ss_flags |= SS_ONSTACK;
                    605:        } else
                    606:                sp = tf->tf_rsp - 128;
                    607:
                    608:        sp &= ~15ULL;   /* just in case */
                    609:        sss = (sizeof(ksc) + 15) & ~15;
                    610:
                    611:        if (p->p_md.md_flags & MDP_USEDFPU) {
                    612:                fpusave_proc(p, 1);
                    613:                sp -= sizeof(struct fxsave64);
                    614:                ksc.sc_fpstate = (struct fxsave64 *)sp;
                    615:                if (copyout(&p->p_addr->u_pcb.pcb_savefpu.fp_fxsave,
                    616:                    (void *)sp, sizeof(struct fxsave64)))
                    617:                        sigexit(p, SIGILL);
                    618:        }
                    619:
                    620:        sip = 0;
                    621:        if (psp->ps_siginfo & sigmask(sig)) {
                    622:                sip = sp - ((sizeof(ksi) + 15) & ~15);
                    623:                sss += (sizeof(ksi) + 15) & ~15;
                    624:
                    625:                initsiginfo(&ksi, sig, code, type, val);
                    626:                if (copyout(&ksi, (void *)sip, sizeof(ksi)))
                    627:                        sigexit(p, SIGILL);
                    628:        }
                    629:        scp = sp - sss;
                    630:
                    631:        if (copyout(&ksc, (void *)scp, sizeof(ksc)))
                    632:                sigexit(p, SIGILL);
                    633:
                    634:        /*
                    635:         * Build context to run handler in.
                    636:         */
                    637:        tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL);
                    638:        tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL);
                    639:        tf->tf_fs = LSEL(LUDATA_SEL, SEL_UPL);
                    640:        tf->tf_gs = LSEL(LUDATA_SEL, SEL_UPL);
                    641:
                    642:        tf->tf_rax = (u_int64_t)catcher;
                    643:        tf->tf_rdi = sig;
                    644:        tf->tf_rsi = sip;
                    645:        tf->tf_rdx = scp;
                    646:
                    647:        tf->tf_rip = (u_int64_t)p->p_sigcode;
                    648:        tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL);
                    649:        tf->tf_rflags &= ~(PSL_T|PSL_VM|PSL_AC);
                    650:        tf->tf_rsp = scp;
                    651:        tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL);
                    652:
                    653: #ifdef DEBUG
                    654:        if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
                    655:                printf("sendsig(%d): pc 0x%x, catcher 0x%x\n", p->p_pid,
                    656:                    tf->tf_rip, tf->tf_rax);
                    657: #endif
                    658: }
                    659:
                    660: /*
                    661:  * System call to cleanup state after a signal
                    662:  * has been taken.  Reset signal mask and
                    663:  * stack state from context left by sendsig (above).
                    664:  * Return to previous pc and psl as specified by
                    665:  * context left by sendsig. Check carefully to
                    666:  * make sure that the user has not modified the
                    667:  * psl to gain improper privileges or to cause
                    668:  * a machine fault.
                    669:  */
                    670: int
                    671: sys_sigreturn(struct proc *p, void *v, register_t *retval)
                    672: {
                    673:        struct sys_sigreturn_args /* {
                    674:                syscallarg(struct sigcontext *) sigcntxp;
                    675:        } */ *uap = v;
                    676:        struct sigcontext *scp, ksc;
                    677:        struct trapframe *tf = p->p_md.md_regs;
                    678:        int error;
                    679:
                    680:        scp = SCARG(uap, sigcntxp);
                    681: #ifdef DEBUG
                    682:        if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
                    683:                printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
                    684: #endif
                    685:        if ((error = copyin((caddr_t)scp, &ksc, sizeof ksc)))
                    686:                return (error);
                    687:
                    688:        if (((ksc.sc_rflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0 ||
                    689:            !USERMODE(ksc.sc_cs, ksc.sc_eflags))
                    690:                return (EINVAL);
                    691:
                    692:        if (p->p_md.md_flags & MDP_USEDFPU)
                    693:                fpusave_proc(p, 0);
                    694:
                    695:        if (ksc.sc_fpstate && (error = copyin(ksc.sc_fpstate,
                    696:            &p->p_addr->u_pcb.pcb_savefpu.fp_fxsave, sizeof (struct fxsave64))))
                    697:                return (error);
                    698:
                    699:        ksc.sc_trapno = tf->tf_trapno;
                    700:        ksc.sc_err = tf->tf_err;
                    701:        bcopy(&ksc, tf, sizeof(*tf));
                    702:
                    703:        /* Restore signal stack. */
                    704:        if (ksc.sc_onstack)
                    705:                p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
                    706:        else
                    707:                p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
                    708:        p->p_sigmask = ksc.sc_mask & ~sigcantmask;
                    709:
                    710:        return (EJUSTRETURN);
                    711: }
                    712:
                    713: /*
                    714:  * Notify the current process (p) that it has a signal pending,
                    715:  * process as soon as possible.
                    716:  */
                    717: void
                    718: signotify(struct proc *p)
                    719: {
                    720:        aston(p);
                    721: #ifdef MULTIPROCESSOR
                    722:        if (p->p_cpu != curcpu() && p->p_cpu != NULL)
                    723:                x86_send_ipi(p->p_cpu, X86_IPI_NOP);
                    724: #endif
                    725: }
                    726:
                    727: int    waittime = -1;
                    728: struct pcb dumppcb;
                    729:
                    730: void
                    731: boot(int howto)
                    732: {
                    733:
                    734:        if (cold) {
                    735:                /*
                    736:                 * If the system is cold, just halt, unless the user
                    737:                 * explicitly asked for reboot.
                    738:                 */
                    739:                if ((howto & RB_USERREQ) == 0)
                    740:                        howto |= RB_HALT;
                    741:                goto haltsys;
                    742:        }
                    743:
                    744:        boothowto = howto;
                    745:        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
                    746:                waittime = 0;
                    747:
                    748:                if (curproc == NULL)
                    749:                        curproc = &proc0;       /* XXX */
                    750:                vfs_shutdown();
                    751:                /*
                    752:                 * If we've been adjusting the clock, the todr
                    753:                 * will be out of synch; adjust it now.
                    754:                 */
                    755:                if ((howto & RB_TIMEBAD) == 0) {
                    756:                        resettodr();
                    757:                } else {
                    758:                        printf("WARNING: not updating battery clock\n");
                    759:                }
                    760:        }
                    761:
                    762:        /* Disable interrupts. */
                    763:        splhigh();
                    764:
                    765:        /* Do a dump if requested. */
                    766:        if (howto & RB_DUMP)
                    767:                dumpsys();
                    768:
                    769: haltsys:
                    770:        doshutdownhooks();
                    771:
                    772: #ifdef MULTIPROCESSOR
                    773:        x86_broadcast_ipi(X86_IPI_HALT);
                    774: #endif
                    775:
                    776:        if (howto & RB_HALT) {
                    777: #if NACPI > 0 && !defined(SMALL_KERNEL)
                    778:                extern int acpi_s5, acpi_enabled;
                    779:
                    780:                if (acpi_enabled) {
                    781:                        delay(500000);
                    782:                        if (howto & RB_POWERDOWN || acpi_s5)
                    783:                                acpi_powerdown();
                    784:                }
                    785: #endif
                    786:                printf("\n");
                    787:                printf("The operating system has halted.\n");
                    788:                printf("Please press any key to reboot.\n\n");
                    789:                cnpollc(1);     /* for proper keyboard command handling */
                    790:                cngetc();
                    791:                cnpollc(0);
                    792:        }
                    793:
                    794:        printf("rebooting...\n");
                    795:        if (cpureset_delay > 0)
                    796:                delay(cpureset_delay * 1000);
                    797:        cpu_reset();
                    798:        for(;;) ;
                    799:        /*NOTREACHED*/
                    800: }
                    801:
                    802: /*
                    803:  * XXXfvdl share dumpcode.
                    804:  */
                    805:
                    806: /*
                    807:  * These variables are needed by /sbin/savecore
                    808:  */
                    809: u_int32_t      dumpmag = 0x8fca0101;   /* magic number */
                    810: int    dumpsize = 0;           /* pages */
                    811: long   dumplo = 0;             /* blocks */
                    812:
                    813: /*
                    814:  * cpu_dump: dump the machine-dependent kernel core dump headers.
                    815:  */
                    816: int
                    817: cpu_dump(void)
                    818: {
                    819:        int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
                    820:        char buf[dbtob(1)];
                    821:        kcore_seg_t *segp;
                    822:        cpu_kcore_hdr_t *cpuhdrp;
                    823:        phys_ram_seg_t *memsegp;
                    824:        int i;
                    825:
                    826:        dump = bdevsw[major(dumpdev)].d_dump;
                    827:
                    828:        memset(buf, 0, sizeof buf);
                    829:        segp = (kcore_seg_t *)buf;
                    830:        cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp))];
                    831:        memsegp = (phys_ram_seg_t *)&buf[ALIGN(sizeof(*segp)) +
                    832:            ALIGN(sizeof(*cpuhdrp))];
                    833:
                    834:        /*
                    835:         * Generate a segment header.
                    836:         */
                    837:        CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
                    838:        segp->c_size = dbtob(1) - ALIGN(sizeof(*segp));
                    839:
                    840:        /*
                    841:         * Add the machine-dependent header info.
                    842:         */
                    843:        cpuhdrp->ptdpaddr = PTDpaddr;
                    844:        cpuhdrp->nmemsegs = mem_cluster_cnt;
                    845:
                    846:        /*
                    847:         * Fill in the memory segment descriptors.
                    848:         */
                    849:        for (i = 0; i < mem_cluster_cnt; i++) {
                    850:                memsegp[i].start = mem_clusters[i].start;
                    851:                memsegp[i].size = mem_clusters[i].size & ~PAGE_MASK;
                    852:        }
                    853:
                    854:        return (dump(dumpdev, dumplo, (caddr_t)buf, dbtob(1)));
                    855: }
                    856:
                    857: /*
                    858:  * This is called by main to set dumplo and dumpsize.
                    859:  * Dumps always skip the first PAGE_SIZE of disk space
                    860:  * in case there might be a disk label stored there.
                    861:  * If there is extra space, put dump at the end to
                    862:  * reduce the chance that swapping trashes it.
                    863:  */
                    864: void
                    865: dumpconf(void)
                    866: {
                    867:        int nblks, dumpblks;    /* size of dump area */
                    868:
                    869:        if (dumpdev == NODEV ||
                    870:            (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
                    871:                return;
                    872:        if (nblks <= ctod(1))
                    873:                return;
                    874:
                    875:        dumpblks = cpu_dumpsize();
                    876:        if (dumpblks < 0)
                    877:                return;
                    878:        dumpblks += ctod(cpu_dump_mempagecnt());
                    879:
                    880:        /* If dump won't fit (incl. room for possible label), punt. */
                    881:        if (dumpblks > (nblks - ctod(1)))
                    882:                return;
                    883:
                    884:        /* Put dump at end of partition */
                    885:        dumplo = nblks - dumpblks;
                    886:
                    887:        /* dumpsize is in page units, and doesn't include headers. */
                    888:        dumpsize = cpu_dump_mempagecnt();
                    889: }
                    890:
                    891: /*
                    892:  * Doadump comes here after turning off memory management and
                    893:  * getting on the dump stack, either when called above, or by
                    894:  * the auto-restart code.
                    895:  */
                    896: #define BYTES_PER_DUMP  PAGE_SIZE /* must be a multiple of pagesize XXX small */
                    897: static vaddr_t dumpspace;
                    898:
                    899: vaddr_t
                    900: reserve_dumppages(vaddr_t p)
                    901: {
                    902:
                    903:        dumpspace = p;
                    904:        return (p + BYTES_PER_DUMP);
                    905: }
                    906:
                    907: void
                    908: dumpsys(void)
                    909: {
                    910:        u_long totalbytesleft, bytes, i, n, memseg;
                    911:        u_long maddr;
                    912:        daddr64_t blkno;
                    913:        int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
                    914:        int error;
                    915:
                    916:        /* Save registers. */
                    917:        savectx(&dumppcb);
                    918:
                    919:        if (dumpdev == NODEV)
                    920:                return;
                    921:
                    922:        /*
                    923:         * For dumps during autoconfiguration,
                    924:         * if dump device has already configured...
                    925:         */
                    926:        if (dumpsize == 0)
                    927:                dumpconf();
                    928:        if (dumplo <= 0 || dumpsize == 0) {
                    929:                printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
                    930:                    minor(dumpdev));
                    931:                return;
                    932:        }
                    933:        printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
                    934:            minor(dumpdev), dumplo);
                    935:
                    936:        error = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
                    937:        printf("dump ");
                    938:        if (error == -1) {
                    939:                printf("area unavailable\n");
                    940:                return;
                    941:        }
                    942:
                    943:        if ((error = cpu_dump()) != 0)
                    944:                goto err;
                    945:
                    946:        totalbytesleft = ptoa(cpu_dump_mempagecnt());
                    947:        blkno = dumplo + cpu_dumpsize();
                    948:        dump = bdevsw[major(dumpdev)].d_dump;
                    949:        error = 0;
                    950:
                    951:        for (memseg = 0; memseg < mem_cluster_cnt; memseg++) {
                    952:                maddr = mem_clusters[memseg].start;
                    953:                bytes = mem_clusters[memseg].size;
                    954:
                    955:                for (i = 0; i < bytes; i += n, totalbytesleft -= n) {
                    956:                        /* Print out how many MBs we have left to go. */
                    957:                        if ((totalbytesleft % (1024*1024)) == 0)
                    958:                                printf("%ld ", totalbytesleft / (1024 * 1024));
                    959:
                    960:                        /* Limit size for next transfer. */
                    961:                        n = bytes - i;
                    962:                        if (n > BYTES_PER_DUMP)
                    963:                                n = BYTES_PER_DUMP;
                    964:
                    965:                        (void) pmap_map(dumpspace, maddr, maddr + n,
                    966:                            VM_PROT_READ);
                    967:
                    968:                        error = (*dump)(dumpdev, blkno, (caddr_t)dumpspace, n);
                    969:                        if (error)
                    970:                                goto err;
                    971:                        maddr += n;
                    972:                        blkno += btodb(n);              /* XXX? */
                    973:
                    974: #if 0  /* XXX this doesn't work.  grr. */
                    975:                        /* operator aborting dump? */
                    976:                        if (sget() != NULL) {
                    977:                                error = EINTR;
                    978:                                break;
                    979:                        }
                    980: #endif
                    981:                }
                    982:        }
                    983:
                    984:  err:
                    985:        switch (error) {
                    986:
                    987:        case ENXIO:
                    988:                printf("device bad\n");
                    989:                break;
                    990:
                    991:        case EFAULT:
                    992:                printf("device not ready\n");
                    993:                break;
                    994:
                    995:        case EINVAL:
                    996:                printf("area improper\n");
                    997:                break;
                    998:
                    999:        case EIO:
                   1000:                printf("i/o error\n");
                   1001:                break;
                   1002:
                   1003:        case EINTR:
                   1004:                printf("aborted from console\n");
                   1005:                break;
                   1006:
                   1007:        case 0:
                   1008:                printf("succeeded\n");
                   1009:                break;
                   1010:
                   1011:        default:
                   1012:                printf("error %d\n", error);
                   1013:                break;
                   1014:        }
                   1015:        printf("\n\n");
                   1016:        delay(5000000);         /* 5 seconds */
                   1017: }
                   1018:
                   1019: /*
                   1020:  * Clear registers on exec
                   1021:  */
                   1022: void
                   1023: setregs(struct proc *p, struct exec_package *pack, u_long stack,
                   1024:     register_t *retval)
                   1025: {
                   1026:        struct pcb *pcb = &p->p_addr->u_pcb;
                   1027:        struct trapframe *tf;
                   1028:
                   1029:        /* If we were using the FPU, forget about it. */
                   1030:        if (p->p_addr->u_pcb.pcb_fpcpu != NULL)
                   1031:                fpusave_proc(p, 0);
                   1032:
                   1033: #ifdef USER_LDT
                   1034:        pmap_ldt_cleanup(p);
                   1035: #endif
                   1036:
                   1037:        p->p_md.md_flags &= ~MDP_USEDFPU;
                   1038:        pcb->pcb_flags = 0;
                   1039:        pcb->pcb_savefpu.fp_fxsave.fx_fcw = __INITIAL_NPXCW__;
                   1040:        pcb->pcb_savefpu.fp_fxsave.fx_mxcsr = __INITIAL_MXCSR__;
                   1041:        pcb->pcb_savefpu.fp_fxsave.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
                   1042:
                   1043:        tf = p->p_md.md_regs;
                   1044:        tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL);
                   1045:        tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL);
                   1046:        tf->tf_fs = LSEL(LUDATA_SEL, SEL_UPL);
                   1047:        tf->tf_gs = LSEL(LUDATA_SEL, SEL_UPL);
                   1048:        tf->tf_rdi = 0;
                   1049:        tf->tf_rsi = 0;
                   1050:        tf->tf_rbp = 0;
                   1051:        tf->tf_rbx = 0;
                   1052:        tf->tf_rdx = 0;
                   1053:        tf->tf_rcx = 0;
                   1054:        tf->tf_rax = 0;
                   1055:        tf->tf_rip = pack->ep_entry;
                   1056:        tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL);
                   1057:        tf->tf_rflags = PSL_USERSET;
                   1058:        tf->tf_rsp = stack;
                   1059:        tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL);
                   1060:
                   1061:        retval[1] = 0;
                   1062: }
                   1063:
                   1064: /*
                   1065:  * Initialize segments and descriptor tables
                   1066:  */
                   1067:
                   1068: struct gate_descriptor *idt;
                   1069: char idt_allocmap[NIDT];
                   1070: struct simplelock idt_lock;
                   1071: char *ldtstore;
                   1072: char *gdtstore;
                   1073: extern  struct user *proc0paddr;
                   1074:
                   1075: void
                   1076: setgate(struct gate_descriptor *gd, void *func, int ist, int type, int dpl,
                   1077:     int sel)
                   1078: {
                   1079:        gd->gd_looffset = (u_int64_t)func & 0xffff;
                   1080:        gd->gd_selector = sel;
                   1081:        gd->gd_ist = ist;
                   1082:        gd->gd_type = type;
                   1083:        gd->gd_dpl = dpl;
                   1084:        gd->gd_p = 1;
                   1085:        gd->gd_hioffset = (u_int64_t)func >> 16;
                   1086:        gd->gd_zero = 0;
                   1087:        gd->gd_xx1 = 0;
                   1088:        gd->gd_xx2 = 0;
                   1089:        gd->gd_xx3 = 0;
                   1090: }
                   1091:
                   1092: void
                   1093: unsetgate(struct gate_descriptor *gd)
                   1094: {
                   1095:        memset(gd, 0, sizeof (*gd));
                   1096: }
                   1097:
                   1098: void
                   1099: setregion(struct region_descriptor *rd, void *base, u_int16_t limit)
                   1100: {
                   1101:        rd->rd_limit = limit;
                   1102:        rd->rd_base = (u_int64_t)base;
                   1103: }
                   1104:
                   1105: /*
                   1106:  * Note that the base and limit fields are ignored in long mode.
                   1107:  */
                   1108: void
                   1109: set_mem_segment(struct mem_segment_descriptor *sd, void *base, size_t limit,
                   1110:     int type, int dpl, int gran, int def32, int is64)
                   1111: {
                   1112:        sd->sd_lolimit = (unsigned)limit;
                   1113:        sd->sd_lobase = (unsigned long)base;
                   1114:        sd->sd_type = type;
                   1115:        sd->sd_dpl = dpl;
                   1116:        sd->sd_p = 1;
                   1117:        sd->sd_hilimit = (unsigned)limit >> 16;
                   1118:        sd->sd_avl = 0;
                   1119:        sd->sd_long = is64;
                   1120:        sd->sd_def32 = def32;
                   1121:        sd->sd_gran = gran;
                   1122:        sd->sd_hibase = (unsigned long)base >> 24;
                   1123: }
                   1124:
                   1125: void
                   1126: set_sys_segment(struct sys_segment_descriptor *sd, void *base, size_t limit,
                   1127:     int type, int dpl, int gran)
                   1128: {
                   1129:        memset(sd, 0, sizeof *sd);
                   1130:        sd->sd_lolimit = (unsigned)limit;
                   1131:        sd->sd_lobase = (u_int64_t)base;
                   1132:        sd->sd_type = type;
                   1133:        sd->sd_dpl = dpl;
                   1134:        sd->sd_p = 1;
                   1135:        sd->sd_hilimit = (unsigned)limit >> 16;
                   1136:        sd->sd_gran = gran;
                   1137:        sd->sd_hibase = (u_int64_t)base >> 24;
                   1138: }
                   1139:
                   1140: void cpu_init_idt(void)
                   1141: {
                   1142:        struct region_descriptor region;
                   1143:
                   1144:        setregion(&region, idt, NIDT * sizeof(idt[0]) - 1);
                   1145:        lidt(&region);
                   1146: }
                   1147:
                   1148:
                   1149: #define        IDTVEC(name)    __CONCAT(X, name)
                   1150: typedef void (vector)(void);
                   1151: extern vector IDTVEC(syscall);
                   1152: extern vector IDTVEC(syscall32);
                   1153: extern vector IDTVEC(osyscall);
                   1154: extern vector IDTVEC(oosyscall);
                   1155: extern vector *IDTVEC(exceptions)[];
                   1156:
                   1157: #define        KBTOB(x)        ((size_t)(x) * 1024UL)
                   1158:
                   1159: void
                   1160: init_x86_64(paddr_t first_avail)
                   1161: {
                   1162:        extern void consinit(void);
                   1163:        extern struct extent *iomem_ex;
                   1164:        struct region_descriptor region;
                   1165:        struct mem_segment_descriptor *ldt_segp;
                   1166:        int x, first16q, ist;
                   1167:        u_int64_t seg_start, seg_end;
                   1168:        u_int64_t seg_start1, seg_end1;
                   1169:
                   1170:        cpu_init_msrs(&cpu_info_primary);
                   1171:
                   1172:        proc0.p_addr = proc0paddr;
                   1173:        cpu_info_primary.ci_curpcb = &proc0.p_addr->u_pcb;
                   1174:
                   1175:        x86_bus_space_init();
                   1176:
                   1177:        consinit();     /* XXX SHOULD NOT BE DONE HERE */
                   1178:
                   1179:        /*
                   1180:         * Initailize PAGE_SIZE-dependent variables.
                   1181:         */
                   1182:        uvm_setpagesize();
                   1183:
                   1184: #if 0
                   1185:        uvmexp.ncolors = 2;
                   1186: #endif
                   1187:
                   1188:        /*
                   1189:         * Boot arguments are in a single page specified by /boot.
                   1190:         *
                   1191:         * We require the "new" vector form, as well as memory ranges
                   1192:         * to be given in bytes rather than KB.
                   1193:         *
                   1194:         * locore copies the data into bootinfo[] for us.
                   1195:         */
                   1196:        if ((bootapiver & (BAPIV_VECTOR | BAPIV_BMEMMAP)) ==
                   1197:            (BAPIV_VECTOR | BAPIV_BMEMMAP)) {
                   1198:                if (bootinfo_size >= sizeof(bootinfo))
                   1199:                        panic("boot args too big");
                   1200:
                   1201:                getbootinfo(bootinfo, bootinfo_size);
                   1202:        } else
                   1203:                panic("invalid /boot");
                   1204:
                   1205:        avail_start = PAGE_SIZE; /* BIOS leaves data in low memory */
                   1206:                                 /* and VM system doesn't work with phys 0 */
                   1207: #ifdef MULTIPROCESSOR
                   1208:        if (avail_start < MP_TRAMPOLINE + PAGE_SIZE)
                   1209:                avail_start = MP_TRAMPOLINE + PAGE_SIZE;
                   1210: #endif
                   1211:
                   1212:        /*
                   1213:         * Call pmap initialization to make new kernel address space.
                   1214:         * We must do this before loading pages into the VM system.
                   1215:         */
                   1216:        pmap_bootstrap(VM_MIN_KERNEL_ADDRESS,
                   1217:            IOM_END + trunc_page(KBTOB(biosextmem)));
                   1218:
                   1219:        if (avail_start != PAGE_SIZE)
                   1220:                pmap_prealloc_lowmem_ptps();
                   1221:
                   1222:        if (mem_cluster_cnt == 0) {
                   1223:                /*
                   1224:                 * Allocate the physical addresses used by RAM from the iomem
                   1225:                 * extent map.  This is done before the addresses are
                   1226:                 * page rounded just to make sure we get them all.
                   1227:                 */
                   1228:                if (extent_alloc_region(iomem_ex, 0, KBTOB(biosbasemem),
                   1229:                    EX_NOWAIT)) {
                   1230:                        /* XXX What should we do? */
                   1231:                        printf("WARNING: CAN'T ALLOCATE BASE MEMORY FROM "
                   1232:                            "IOMEM EXTENT MAP!\n");
                   1233:                }
                   1234:                mem_clusters[0].start = 0;
                   1235:                mem_clusters[0].size = trunc_page(KBTOB(biosbasemem));
                   1236:                physmem += atop(mem_clusters[0].size);
                   1237:                if (extent_alloc_region(iomem_ex, IOM_END, KBTOB(biosextmem),
                   1238:                    EX_NOWAIT)) {
                   1239:                        /* XXX What should we do? */
                   1240:                        printf("WARNING: CAN'T ALLOCATE EXTENDED MEMORY FROM "
                   1241:                            "IOMEM EXTENT MAP!\n");
                   1242:                }
                   1243: #if 0
                   1244: #if NISADMA > 0
                   1245:                /*
                   1246:                 * Some motherboards/BIOSes remap the 384K of RAM that would
                   1247:                 * normally be covered by the ISA hole to the end of memory
                   1248:                 * so that it can be used.  However, on a 16M system, this
                   1249:                 * would cause bounce buffers to be allocated and used.
                   1250:                 * This is not desirable behaviour, as more than 384K of
                   1251:                 * bounce buffers might be allocated.  As a work-around,
                   1252:                 * we round memory down to the nearest 1M boundary if
                   1253:                 * we're using any isadma devices and the remapped memory
                   1254:                 * is what puts us over 16M.
                   1255:                 */
                   1256:                if (biosextmem > (15*1024) && biosextmem < (16*1024)) {
                   1257:                        char pbuf[9];
                   1258:
                   1259:                        format_bytes(pbuf, sizeof(pbuf),
                   1260:                            biosextmem - (15*1024));
                   1261:                        printf("Warning: ignoring %s of remapped memory\n",
                   1262:                            pbuf);
                   1263:                        biosextmem = (15*1024);
                   1264:                }
                   1265: #endif
                   1266: #endif
                   1267:                mem_clusters[1].start = IOM_END;
                   1268:                mem_clusters[1].size = trunc_page(KBTOB(biosextmem));
                   1269:                physmem += atop(mem_clusters[1].size);
                   1270:
                   1271:                mem_cluster_cnt = 2;
                   1272:
                   1273:                avail_end = IOM_END + trunc_page(KBTOB(biosextmem));
                   1274:        }
                   1275:
                   1276:        /*
                   1277:         * If we have 16M of RAM or less, just put it all on
                   1278:         * the default free list.  Otherwise, put the first
                   1279:         * 16M of RAM on a lower priority free list (so that
                   1280:         * all of the ISA DMA'able memory won't be eaten up
                   1281:         * first-off).
                   1282:         */
                   1283:        if (avail_end <= (16 * 1024 * 1024))
                   1284:                first16q = VM_FREELIST_DEFAULT;
                   1285:        else
                   1286:                first16q = VM_FREELIST_FIRST16;
                   1287:
                   1288:        /* Make sure the end of the space used by the kernel is rounded. */
                   1289:        first_avail = round_page(first_avail);
                   1290:        kern_end = KERNBASE + first_avail;
                   1291:
                   1292:        /*
                   1293:         * Now, load the memory clusters (which have already been
                   1294:         * rounded and truncated) into the VM system.
                   1295:         *
                   1296:         * NOTE: WE ASSUME THAT MEMORY STARTS AT 0 AND THAT THE KERNEL
                   1297:         * IS LOADED AT IOM_END (1M).
                   1298:         */
                   1299:        for (x = 0; x < mem_cluster_cnt; x++) {
                   1300:                seg_start = mem_clusters[x].start;
                   1301:                seg_end = mem_clusters[x].start + mem_clusters[x].size;
                   1302:                seg_start1 = 0;
                   1303:                seg_end1 = 0;
                   1304:
                   1305:                if (seg_start > 0xffffffffULL) {
                   1306:                        printf("skipping %lld bytes of memory above 4GB\n",
                   1307:                            seg_end - seg_start);
                   1308:                        continue;
                   1309:                }
                   1310:                if (seg_end > 0x100000000ULL) {
                   1311:                        printf("skipping %lld bytes of memory above 4GB\n",
                   1312:                            seg_end - 0x100000000ULL);
                   1313:                        seg_end = 0x100000000ULL;
                   1314:                }
                   1315:
                   1316:                /*
                   1317:                 * Skip memory before our available starting point.
                   1318:                 */
                   1319:                if (seg_end <= avail_start)
                   1320:                        continue;
                   1321:
                   1322:                if (avail_start >= seg_start && avail_start < seg_end) {
                   1323:                        if (seg_start != 0)
                   1324:                                panic("init_x86_64: memory doesn't start at 0");
                   1325:                        seg_start = avail_start;
                   1326:                        if (seg_start == seg_end)
                   1327:                                continue;
                   1328:                }
                   1329:
                   1330:                /*
                   1331:                 * If this segment contains the kernel, split it
                   1332:                 * in two, around the kernel.
                   1333:                 */
                   1334:                if (seg_start <= IOM_END && first_avail <= seg_end) {
                   1335:                        seg_start1 = first_avail;
                   1336:                        seg_end1 = seg_end;
                   1337:                        seg_end = IOM_END;
                   1338:                }
                   1339:
                   1340:                /* First hunk */
                   1341:                if (seg_start != seg_end) {
                   1342:                        if (seg_start <= (16 * 1024 * 1024) &&
                   1343:                            first16q != VM_FREELIST_DEFAULT) {
                   1344:                                u_int64_t tmp;
                   1345:
                   1346:                                if (seg_end > (16 * 1024 * 1024))
                   1347:                                        tmp = (16 * 1024 * 1024);
                   1348:                                else
                   1349:                                        tmp = seg_end;
                   1350: #if DEBUG_MEMLOAD
                   1351:                                printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
                   1352:                                    (unsigned long long)seg_start,
                   1353:                                    (unsigned long long)tmp,
                   1354:                                    atop(seg_start), atop(tmp));
                   1355: #endif
                   1356:                                uvm_page_physload(atop(seg_start),
                   1357:                                    atop(tmp), atop(seg_start),
                   1358:                                    atop(tmp), first16q);
                   1359:                                seg_start = tmp;
                   1360:                        }
                   1361:
                   1362:                        if (seg_start != seg_end) {
                   1363: #if DEBUG_MEMLOAD
                   1364:                                printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
                   1365:                                    (unsigned long long)seg_start,
                   1366:                                    (unsigned long long)seg_end,
                   1367:                                    atop(seg_start), atop(seg_end));
                   1368: #endif
                   1369:                                uvm_page_physload(atop(seg_start),
                   1370:                                    atop(seg_end), atop(seg_start),
                   1371:                                    atop(seg_end), VM_FREELIST_DEFAULT);
                   1372:                        }
                   1373:                }
                   1374:
                   1375:                /* Second hunk */
                   1376:                if (seg_start1 != seg_end1) {
                   1377:                        if (seg_start1 <= (16 * 1024 * 1024) &&
                   1378:                            first16q != VM_FREELIST_DEFAULT) {
                   1379:                                u_int64_t tmp;
                   1380:
                   1381:                                if (seg_end1 > (16 * 1024 * 1024))
                   1382:                                        tmp = (16 * 1024 * 1024);
                   1383:                                else
                   1384:                                        tmp = seg_end1;
                   1385: #if DEBUG_MEMLOAD
                   1386:                                printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
                   1387:                                    (unsigned long long)seg_start1,
                   1388:                                    (unsigned long long)tmp,
                   1389:                                    atop(seg_start1), atop(tmp));
                   1390: #endif
                   1391:                                uvm_page_physload(atop(seg_start1),
                   1392:                                    atop(tmp), atop(seg_start1),
                   1393:                                    atop(tmp), first16q);
                   1394:                                seg_start1 = tmp;
                   1395:                        }
                   1396:
                   1397:                        if (seg_start1 != seg_end1) {
                   1398: #if DEBUG_MEMLOAD
                   1399:                                printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
                   1400:                                    (unsigned long long)seg_start1,
                   1401:                                    (unsigned long long)seg_end1,
                   1402:                                    atop(seg_start1), atop(seg_end1));
                   1403: #endif
                   1404:                                uvm_page_physload(atop(seg_start1),
                   1405:                                    atop(seg_end1), atop(seg_start1),
                   1406:                                    atop(seg_end1), VM_FREELIST_DEFAULT);
                   1407:                        }
                   1408:                }
                   1409:        }
                   1410:
                   1411:        /*
                   1412:         * Steal memory for the message buffer (at end of core).
                   1413:         */
                   1414:        {
                   1415:                struct vm_physseg *vps = NULL;
                   1416:                psize_t sz = round_page(MSGBUFSIZE);
                   1417:                psize_t reqsz = sz;
                   1418:
                   1419:                for (x = 0; x < vm_nphysseg; x++) {
                   1420:                        vps = &vm_physmem[x];
                   1421:                        if (ptoa(vps->avail_end) == avail_end)
                   1422:                                break;
                   1423:                }
                   1424:                if (x == vm_nphysseg)
                   1425:                        panic("init_x86_64: can't find end of memory");
                   1426:
                   1427:                /* Shrink so it'll fit in the last segment. */
                   1428:                if ((vps->avail_end - vps->avail_start) < atop(sz))
                   1429:                        sz = ptoa(vps->avail_end - vps->avail_start);
                   1430:
                   1431:                vps->avail_end -= atop(sz);
                   1432:                vps->end -= atop(sz);
                   1433:                msgbuf_paddr = ptoa(vps->avail_end);
                   1434:
                   1435:                /* Remove the last segment if it now has no pages. */
                   1436:                if (vps->start == vps->end) {
                   1437:                        for (vm_nphysseg--; x < vm_nphysseg; x++)
                   1438:                                vm_physmem[x] = vm_physmem[x + 1];
                   1439:                }
                   1440:
                   1441:                /* Now find where the new avail_end is. */
                   1442:                for (avail_end = 0, x = 0; x < vm_nphysseg; x++)
                   1443:                        if (vm_physmem[x].avail_end > avail_end)
                   1444:                                avail_end = vm_physmem[x].avail_end;
                   1445:                avail_end = ptoa(avail_end);
                   1446:
                   1447:                /* Warn if the message buffer had to be shrunk. */
                   1448:                if (sz != reqsz)
                   1449:                        printf("WARNING: %ld bytes not available for msgbuf "
                   1450:                            "in last cluster (%ld used)\n", reqsz, sz);
                   1451:        }
                   1452:
                   1453:        /*
                   1454:         * XXXfvdl todo: acpi wakeup code.
                   1455:         */
                   1456:
                   1457:        pmap_growkernel(VM_MIN_KERNEL_ADDRESS + 32 * 1024 * 1024);
                   1458:
                   1459:        pmap_kenter_pa(idt_vaddr, idt_paddr, VM_PROT_READ|VM_PROT_WRITE);
                   1460:        pmap_kenter_pa(idt_vaddr + PAGE_SIZE, idt_paddr + PAGE_SIZE,
                   1461:            VM_PROT_READ|VM_PROT_WRITE);
                   1462:
                   1463:        pmap_kenter_pa(lo32_vaddr, lo32_paddr, VM_PROT_READ|VM_PROT_WRITE);
                   1464:
                   1465:        idt = (struct gate_descriptor *)idt_vaddr;
                   1466:        gdtstore = (char *)(idt + NIDT);
                   1467:        ldtstore = gdtstore + DYNSEL_START;
                   1468:
                   1469:        /* make gdt gates and memory segments */
                   1470:        set_mem_segment(GDT_ADDR_MEM(gdtstore, GCODE_SEL), 0, 0xfffff, SDT_MEMERA,
                   1471:            SEL_KPL, 1, 0, 1);
                   1472:
                   1473:        set_mem_segment(GDT_ADDR_MEM(gdtstore, GDATA_SEL), 0, 0xfffff, SDT_MEMRWA,
                   1474:            SEL_KPL, 1, 0, 1);
                   1475:
                   1476:        set_sys_segment(GDT_ADDR_SYS(gdtstore, GLDT_SEL), ldtstore, LDT_SIZE - 1,
                   1477:            SDT_SYSLDT, SEL_KPL, 0);
                   1478:
                   1479:        set_mem_segment(GDT_ADDR_MEM(gdtstore, GUCODE_SEL), 0,
                   1480:            atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMERA, SEL_UPL, 1, 0, 1);
                   1481:
                   1482:        set_mem_segment(GDT_ADDR_MEM(gdtstore, GUDATA_SEL), 0,
                   1483:            atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMRWA, SEL_UPL, 1, 0, 1);
                   1484:
                   1485:        /* make ldt gates and memory segments */
                   1486:        setgate((struct gate_descriptor *)(ldtstore + LSYS5CALLS_SEL),
                   1487:            &IDTVEC(oosyscall), 0, SDT_SYS386CGT, SEL_UPL,
                   1488:            GSEL(GCODE_SEL, SEL_KPL));
                   1489:
                   1490:        *(struct mem_segment_descriptor *)(ldtstore + LUCODE_SEL) =
                   1491:            *GDT_ADDR_MEM(gdtstore, GUCODE_SEL);
                   1492:        *(struct mem_segment_descriptor *)(ldtstore + LUDATA_SEL) =
                   1493:            *GDT_ADDR_MEM(gdtstore, GUDATA_SEL);
                   1494:
                   1495:        /*
                   1496:         * 32 bit GDT entries.
                   1497:         */
                   1498:
                   1499:        set_mem_segment(GDT_ADDR_MEM(gdtstore, GUCODE32_SEL), 0,
                   1500:            atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMERA, SEL_UPL, 1, 1, 0);
                   1501:
                   1502:        set_mem_segment(GDT_ADDR_MEM(gdtstore, GUDATA32_SEL), 0,
                   1503:            atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMRWA, SEL_UPL, 1, 1, 0);
                   1504:
                   1505:        /*
                   1506:         * 32 bit LDT entries.
                   1507:         */
                   1508:        ldt_segp = (struct mem_segment_descriptor *)(ldtstore + LUCODE32_SEL);
                   1509:        set_mem_segment(ldt_segp, 0, atop(VM_MAXUSER_ADDRESS32) - 1,
                   1510:            SDT_MEMERA, SEL_UPL, 1, 1, 0);
                   1511:        ldt_segp = (struct mem_segment_descriptor *)(ldtstore + LUDATA32_SEL);
                   1512:        set_mem_segment(ldt_segp, 0, atop(VM_MAXUSER_ADDRESS32) - 1,
                   1513:            SDT_MEMRWA, SEL_UPL, 1, 1, 0);
                   1514:
                   1515:        /*
                   1516:         * Other entries.
                   1517:         */
                   1518:        memcpy((struct gate_descriptor *)(ldtstore + LSOL26CALLS_SEL),
                   1519:            (struct gate_descriptor *)(ldtstore + LSYS5CALLS_SEL),
                   1520:            sizeof (struct gate_descriptor));
                   1521:        memcpy((struct gate_descriptor *)(ldtstore + LBSDICALLS_SEL),
                   1522:            (struct gate_descriptor *)(ldtstore + LSYS5CALLS_SEL),
                   1523:            sizeof (struct gate_descriptor));
                   1524:
                   1525:        /* exceptions */
                   1526:        for (x = 0; x < 32; x++) {
                   1527:                ist = (x == 8) ? 1 : 0;
                   1528:                setgate(&idt[x], IDTVEC(exceptions)[x], ist, SDT_SYS386IGT,
                   1529:                    (x == 3 || x == 4) ? SEL_UPL : SEL_KPL,
                   1530:                    GSEL(GCODE_SEL, SEL_KPL));
                   1531:                idt_allocmap[x] = 1;
                   1532:        }
                   1533:
                   1534:        /* new-style interrupt gate for syscalls */
                   1535:        setgate(&idt[128], &IDTVEC(osyscall), 0, SDT_SYS386IGT, SEL_UPL,
                   1536:            GSEL(GCODE_SEL, SEL_KPL));
                   1537:        idt_allocmap[128] = 1;
                   1538:
                   1539:        setregion(&region, gdtstore, DYNSEL_START - 1);
                   1540:        lgdt(&region);
                   1541:
                   1542:        cpu_init_idt();
                   1543:
                   1544: #ifdef DDB
                   1545:        db_machine_init();
                   1546:        ddb_init();
                   1547:        if (boothowto & RB_KDB)
                   1548:                Debugger();
                   1549: #endif
                   1550: #ifdef KGDB
                   1551:        kgdb_port_init();
                   1552:        if (boothowto & RB_KDB) {
                   1553:                kgdb_debug_init = 1;
                   1554:                kgdb_connect(1);
                   1555:        }
                   1556: #endif
                   1557:
                   1558:        intr_default_setup();
                   1559:
                   1560:        softintr_init();
                   1561:        splraise(IPL_IPI);
                   1562:        enable_intr();
                   1563:
                   1564:         /* Make sure maxproc is sane */
                   1565:         if (maxproc > cpu_maxproc())
                   1566:                 maxproc = cpu_maxproc();
                   1567: }
                   1568:
                   1569: #ifdef KGDB
                   1570: void
                   1571: kgdb_port_init(void)
                   1572: {
                   1573: #if NCOM > 0
                   1574:        if (!strcmp(kgdb_devname, "com")) {
                   1575:                bus_space_tag_t tag = X86_BUS_SPACE_IO;
                   1576:                com_kgdb_attach(tag, comkgdbaddr, comkgdbrate, COM_FREQ,
                   1577:                    comkgdbmode);
                   1578:        }
                   1579: #endif
                   1580: }
                   1581: #endif /* KGDB */
                   1582:
                   1583: void
                   1584: cpu_reset(void)
                   1585: {
                   1586:
                   1587:        disable_intr();
                   1588:
                   1589:        /*
                   1590:         * The keyboard controller has 4 random output pins, one of which is
                   1591:         * connected to the RESET pin on the CPU in many PCs.  We tell the
                   1592:         * keyboard controller to pulse this line a couple of times.
                   1593:         */
                   1594:        outb(IO_KBD + KBCMDP, KBC_PULSE0);
                   1595:        delay(100000);
                   1596:        outb(IO_KBD + KBCMDP, KBC_PULSE0);
                   1597:        delay(100000);
                   1598:
                   1599:        /*
                   1600:         * Try to cause a triple fault and watchdog reset by making the IDT
                   1601:         * invalid and causing a fault.
                   1602:         */
                   1603:        memset((caddr_t)idt, 0, NIDT * sizeof(idt[0]));
                   1604:        __asm __volatile("divl %0,%1" : : "q" (0), "a" (0));
                   1605:
                   1606: #if 0
                   1607:        /*
                   1608:         * Try to cause a triple fault and watchdog reset by unmapping the
                   1609:         * entire address space and doing a TLB flush.
                   1610:         */
                   1611:        memset((caddr_t)PTD, 0, PAGE_SIZE);
                   1612:        tlbflush();
                   1613: #endif
                   1614:
                   1615:        for (;;);
                   1616: }
                   1617:
                   1618: /*
                   1619:  * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers.
                   1620:  */
                   1621: int
                   1622: cpu_dumpsize(void)
                   1623: {
                   1624:        int size;
                   1625:
                   1626:        size = ALIGN(sizeof(kcore_seg_t)) +
                   1627:            ALIGN(mem_cluster_cnt * sizeof(phys_ram_seg_t));
                   1628:        if (roundup(size, dbtob(1)) != dbtob(1))
                   1629:                return (-1);
                   1630:
                   1631:        return (1);
                   1632: }
                   1633:
                   1634: /*
                   1635:  * cpu_dump_mempagecnt: calculate the size of RAM (in pages) to be dumped.
                   1636:  */
                   1637: u_long
                   1638: cpu_dump_mempagecnt(void)
                   1639: {
                   1640:        u_long i, n;
                   1641:
                   1642:        n = 0;
                   1643:        for (i = 0; i < mem_cluster_cnt; i++)
                   1644:                n += atop(mem_clusters[i].size);
                   1645:        return (n);
                   1646: }
                   1647:
                   1648: void
                   1649: cpu_initclocks(void)
                   1650: {
                   1651:        (*initclock_func)();
                   1652:
                   1653:        if (initclock_func == i8254_initclocks)
                   1654:                i8254_inittimecounter();
                   1655:        else
                   1656:                i8254_inittimecounter_simple();
                   1657: }
                   1658:
                   1659: void
                   1660: need_resched(struct cpu_info *ci)
                   1661: {
                   1662:        ci->ci_want_resched = 1;
                   1663:        if ((ci)->ci_curproc != NULL)
                   1664:                aston((ci)->ci_curproc);
                   1665: }
                   1666:
                   1667: /*
                   1668:  * Allocate an IDT vector slot within the given range.
                   1669:  * XXX needs locking to avoid MP allocation races.
                   1670:  * XXXfvdl share idt code
                   1671:  */
                   1672:
                   1673: int
                   1674: idt_vec_alloc(int low, int high)
                   1675: {
                   1676:        int vec;
                   1677:
                   1678:        simple_lock(&idt_lock);
                   1679:        for (vec = low; vec <= high; vec++) {
                   1680:                if (idt_allocmap[vec] == 0) {
                   1681:                        idt_allocmap[vec] = 1;
                   1682:                        simple_unlock(&idt_lock);
                   1683:                        return vec;
                   1684:                }
                   1685:        }
                   1686:        simple_unlock(&idt_lock);
                   1687:        return 0;
                   1688: }
                   1689:
                   1690: void
                   1691: idt_vec_set(int vec, void (*function)(void))
                   1692: {
                   1693:        /*
                   1694:         * Vector should be allocated, so no locking needed.
                   1695:         */
                   1696:        KASSERT(idt_allocmap[vec] == 1);
                   1697:        setgate(&idt[vec], function, 0, SDT_SYS386IGT, SEL_KPL,
                   1698:            GSEL(GCODE_SEL, SEL_KPL));
                   1699: }
                   1700:
                   1701: void
                   1702: idt_vec_free(int vec)
                   1703: {
                   1704:        simple_lock(&idt_lock);
                   1705:        unsetgate(&idt[vec]);
                   1706:        idt_allocmap[vec] = 0;
                   1707:        simple_unlock(&idt_lock);
                   1708: }
                   1709:
                   1710: /*
                   1711:  * Number of processes is limited by number of available GDT slots.
                   1712:  */
                   1713: int
                   1714: cpu_maxproc(void)
                   1715: {
                   1716: #ifdef USER_LDT
                   1717:        return ((MAXGDTSIZ - DYNSEL_START) / 32);
                   1718: #else
                   1719:        return (MAXGDTSIZ - DYNSEL_START) / 16;
                   1720: #endif
                   1721: }
                   1722:
                   1723: #ifdef DIAGNOSTIC
                   1724: void
                   1725: splassert_check(int wantipl, const char *func)
                   1726: {
                   1727:        int cpl = curcpu()->ci_ilevel;
                   1728:
                   1729:        if (cpl < wantipl) {
                   1730:                splassert_fail(wantipl, cpl, func);
                   1731:        }
                   1732: }
                   1733: #endif
                   1734:
                   1735: void
                   1736: getbootinfo(char *bootinfo, int bootinfo_size)
                   1737: {
                   1738:        bootarg32_t *q;
                   1739:
                   1740: #undef BOOTINFO_DEBUG
                   1741: #ifdef BOOTINFO_DEBUG
                   1742:        printf("bootargv:");
                   1743: #endif
                   1744:
                   1745:        for (q = (bootarg32_t *)bootinfo;
                   1746:            (q->ba_type != BOOTARG_END) &&
                   1747:            ((((char *)q) - bootinfo) < bootinfo_size);
                   1748:            q = (bootarg32_t *)(((char *)q) + q->ba_size)) {
                   1749:
                   1750:                switch (q->ba_type) {
                   1751:                case BOOTARG_MEMMAP:
                   1752:                        bios_memmap = (bios_memmap_t *)q->ba_arg;
                   1753: #ifdef BOOTINFO_DEBUG
                   1754:                        printf(" memmap %p", bios_memmap);
                   1755: #endif
                   1756:                        break;
                   1757:                case BOOTARG_DISKINFO:
                   1758:                        bios_diskinfo = (bios_diskinfo_t *)q->ba_arg;
                   1759: #ifdef BOOTINFO_DEBUG
                   1760:                        printf(" diskinfo %p", bios_diskinfo);
                   1761: #endif
                   1762:                        break;
                   1763: #if 0
                   1764: #if NAPM > 0 || defined(DEBUG)
                   1765:                case BOOTARG_APMINFO:
                   1766: #ifdef BOOTINFO_DEBUG
                   1767:                        printf(" apminfo %p", q->ba_arg);
                   1768: #endif
                   1769:                        apm = (bios_apminfo_t *)q->ba_arg;
                   1770:                        break;
                   1771: #endif
                   1772: #endif
                   1773:                case BOOTARG_CKSUMLEN:
                   1774:                        bios_cksumlen = *(u_int32_t *)q->ba_arg;
                   1775: #ifdef BOOTINFO_DEBUG
                   1776:                        printf(" cksumlen %d", bios_cksumlen);
                   1777: #endif
                   1778:                        break;
                   1779: #if 0
                   1780: #if NPCI > 0
                   1781:                case BOOTARG_PCIINFO:
                   1782:                        bios_pciinfo = (bios_pciinfo_t *)q->ba_arg;
                   1783: #ifdef BOOTINFO_DEBUG
                   1784:                        printf(" pciinfo %p", bios_pciinfo);
                   1785: #endif
                   1786:                        break;
                   1787: #endif
                   1788: #endif
                   1789:                case BOOTARG_CONSDEV:
                   1790:                        if (q->ba_size >= sizeof(bios_consdev_t))
                   1791:                        {
                   1792:                                bios_consdev_t *cdp =
                   1793:                                    (bios_consdev_t*)q->ba_arg;
                   1794: #include "com.h"
                   1795: #if NCOM > 0
                   1796:                                extern int comdefaultrate; /* ic/com.c */
                   1797:                                comdefaultrate = cdp->conspeed;
                   1798: #endif
                   1799: #ifdef BOOTINFO_DEBUG
                   1800:                                printf(" console 0x%x:%d",
                   1801:                                    cdp->consdev, cdp->conspeed);
                   1802: #endif
                   1803:                                cnset(cdp->consdev);
                   1804:                        }
                   1805:                        break;
                   1806: #ifdef NFSCLIENT
                   1807:                case BOOTARG_BOOTMAC:
                   1808:                        bios_bootmac = (bios_bootmac_t *)q->ba_arg;
                   1809:                        break;
                   1810: #endif
                   1811:
                   1812:                default:
                   1813: #ifdef BOOTINFO_DEBUG
                   1814:                        printf(" unsupported arg (%d) %p", q->ba_type,
                   1815:                            q->ba_arg);
                   1816: #endif
                   1817:                        break;
                   1818:                }
                   1819:        }
                   1820: #ifdef BOOTINFO_DEBUG
                   1821:        printf("\n");
                   1822: #endif
                   1823: }
                   1824:
                   1825: int
                   1826: check_context(const struct reg *regs, struct trapframe *tf)
                   1827: {
                   1828:        uint16_t sel;
                   1829:
                   1830:        if (((regs->r_rflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0)
                   1831:                return EINVAL;
                   1832:
                   1833:        sel = regs->r_es & 0xffff;
                   1834:        if (sel != 0 && !VALID_USER_DSEL(sel))
                   1835:                return EINVAL;
                   1836:
                   1837:        sel = regs->r_fs & 0xffff;
                   1838:        if (sel != 0 && !VALID_USER_DSEL(sel))
                   1839:                return EINVAL;
                   1840:
                   1841:        sel = regs->r_gs & 0xffff;
                   1842:        if (sel != 0 && !VALID_USER_DSEL(sel))
                   1843:                return EINVAL;
                   1844:
                   1845:        sel = regs->r_ds & 0xffff;
                   1846:        if (!VALID_USER_DSEL(sel))
                   1847:                return EINVAL;
                   1848:
                   1849:        sel = regs->r_ss & 0xffff;
                   1850:        if (!VALID_USER_DSEL(sel))
                   1851:                return EINVAL;
                   1852:
                   1853:        sel = regs->r_cs & 0xffff;
                   1854:        if (!VALID_USER_CSEL(sel))
                   1855:                return EINVAL;
                   1856:
                   1857:        if (regs->r_rip >= VM_MAXUSER_ADDRESS)
                   1858:                return EINVAL;
                   1859:
                   1860:        return 0;
                   1861: }

CVSweb