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

Annotation of sys/arch/alpha/alpha/machdep.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: machdep.c,v 1.110 2007/06/06 17:15:11 deraadt Exp $ */
        !             2: /* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * This code is derived from software contributed to The NetBSD Foundation
        !             9:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
        !            10:  * NASA Ames Research Center and by Chris G. Demetriou.
        !            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) 1994, 1995, 1996 Carnegie-Mellon University.
        !            43:  * All rights reserved.
        !            44:  *
        !            45:  * Author: Chris G. Demetriou
        !            46:  *
        !            47:  * Permission to use, copy, modify and distribute this software and
        !            48:  * its documentation is hereby granted, provided that both the copyright
        !            49:  * notice and this permission notice appear in all copies of the
        !            50:  * software, derivative works or modified versions, and any portions
        !            51:  * thereof, and that both notices appear in supporting documentation.
        !            52:  *
        !            53:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            54:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
        !            55:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            56:  *
        !            57:  * Carnegie Mellon requests users of this software to return to
        !            58:  *
        !            59:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
        !            60:  *  School of Computer Science
        !            61:  *  Carnegie Mellon University
        !            62:  *  Pittsburgh PA 15213-3890
        !            63:  *
        !            64:  * any improvements or extensions that they make and grant Carnegie the
        !            65:  * rights to redistribute these changes.
        !            66:  */
        !            67:
        !            68: #include <sys/param.h>
        !            69: #include <sys/systm.h>
        !            70: #include <sys/signalvar.h>
        !            71: #include <sys/kernel.h>
        !            72: #include <sys/proc.h>
        !            73: #include <sys/sched.h>
        !            74: #include <sys/buf.h>
        !            75: #include <sys/reboot.h>
        !            76: #include <sys/device.h>
        !            77: #include <sys/conf.h>
        !            78: #include <sys/file.h>
        !            79: #include <sys/timeout.h>
        !            80: #include <sys/malloc.h>
        !            81: #include <sys/mbuf.h>
        !            82: #include <sys/msgbuf.h>
        !            83: #include <sys/ioctl.h>
        !            84: #include <sys/tty.h>
        !            85: #include <sys/user.h>
        !            86: #include <sys/exec.h>
        !            87: #include <sys/exec_ecoff.h>
        !            88: #include <uvm/uvm_extern.h>
        !            89: #include <sys/sysctl.h>
        !            90: #include <sys/core.h>
        !            91: #include <sys/kcore.h>
        !            92: #include <machine/kcore.h>
        !            93: #ifndef NO_IEEE
        !            94: #include <machine/fpu.h>
        !            95: #endif
        !            96: #ifdef SYSVMSG
        !            97: #include <sys/msg.h>
        !            98: #endif
        !            99: #include <sys/timetc.h>
        !           100:
        !           101: #include <sys/mount.h>
        !           102: #include <sys/syscallargs.h>
        !           103:
        !           104: #include <dev/cons.h>
        !           105:
        !           106: #include <machine/autoconf.h>
        !           107: #include <machine/cpu.h>
        !           108: #include <machine/reg.h>
        !           109: #include <machine/rpb.h>
        !           110: #include <machine/prom.h>
        !           111: #include <machine/cpuconf.h>
        !           112: #ifndef NO_IEEE
        !           113: #include <machine/ieeefp.h>
        !           114: #endif
        !           115:
        !           116: #include <dev/pci/pcivar.h>
        !           117:
        !           118: #ifdef DDB
        !           119: #include <machine/db_machdep.h>
        !           120: #include <ddb/db_access.h>
        !           121: #include <ddb/db_sym.h>
        !           122: #include <ddb/db_extern.h>
        !           123: #endif
        !           124:
        !           125: int    cpu_dump(void);
        !           126: int    cpu_dumpsize(void);
        !           127: u_long cpu_dump_mempagecnt(void);
        !           128: void   dumpsys(void);
        !           129: caddr_t allocsys(caddr_t);
        !           130: void   identifycpu(void);
        !           131: void   regdump(struct trapframe *framep);
        !           132: void   printregs(struct reg *);
        !           133:
        !           134: /*
        !           135:  * Declare these as initialized data so we can patch them.
        !           136:  */
        !           137: #ifndef BUFCACHEPERCENT
        !           138: #define BUFCACHEPERCENT 10
        !           139: #endif
        !           140:
        !           141: #ifdef BUFPAGES
        !           142: int    bufpages = BUFPAGES;
        !           143: #else
        !           144: int    bufpages = 0;
        !           145: #endif
        !           146: int    bufcachepercent = BUFCACHEPERCENT;
        !           147:
        !           148: struct vm_map *exec_map = NULL;
        !           149: struct vm_map *phys_map = NULL;
        !           150:
        !           151: #ifdef APERTURE
        !           152: #ifdef INSECURE
        !           153: int allowaperture = 1;
        !           154: #else
        !           155: int allowaperture = 0;
        !           156: #endif
        !           157: #endif
        !           158:
        !           159: int    totalphysmem;           /* total amount of physical memory in system */
        !           160: int    physmem;                /* physical mem used by OpenBSD + some rsvd */
        !           161: int    resvmem;                /* amount of memory reserved for PROM */
        !           162: int    unusedmem;              /* amount of memory for OS that we don't use */
        !           163: int    unknownmem;             /* amount of memory with an unknown use */
        !           164:
        !           165: int    cputype;                /* system type, from the RPB */
        !           166: int    alpha_cpus;
        !           167:
        !           168: int    bootdev_debug = 0;      /* patchable, or from DDB */
        !           169:
        !           170: /* the following is used externally (sysctl_hw) */
        !           171: char   machine[] = MACHINE;            /* from <machine/param.h> */
        !           172: char   cpu_model[128];
        !           173: char   root_device[17];
        !           174:
        !           175: struct user *proc0paddr;
        !           176:
        !           177: /* Number of machine cycles per microsecond */
        !           178: u_int64_t      cycles_per_usec;
        !           179:
        !           180: struct bootinfo_kernel bootinfo;
        !           181:
        !           182: /* For built-in TCDS */
        !           183: #if defined(DEC_3000_300) || defined(DEC_3000_500)
        !           184: u_int8_t       dec_3000_scsiid[2], dec_3000_scsifast[2];
        !           185: #endif
        !           186:
        !           187: struct platform platform;
        !           188:
        !           189: /* for cpu_sysctl() */
        !           190: int    alpha_unaligned_print = 1;      /* warn about unaligned accesses */
        !           191: int    alpha_unaligned_fix = 1;        /* fix up unaligned accesses */
        !           192: int    alpha_unaligned_sigbus = 1;     /* SIGBUS on fixed-up accesses */
        !           193: #ifndef NO_IEEE
        !           194: int    alpha_fp_sync_complete = 0;     /* fp fixup if sync even without /s */
        !           195: #endif
        !           196:
        !           197: /* used by hw_sysctl */
        !           198: extern char *hw_serial;
        !           199:
        !           200: /*
        !           201:  * XXX This should be dynamically sized, but we have the chicken-egg problem!
        !           202:  * XXX it should also be larger than it is, because not all of the mddt
        !           203:  * XXX clusters end up being used for VM.
        !           204:  */
        !           205: phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];   /* low size bits overloaded */
        !           206: int    mem_cluster_cnt;
        !           207:
        !           208: void
        !           209: alpha_init(pfn, ptb, bim, bip, biv)
        !           210:        u_long pfn;             /* first free PFN number */
        !           211:        u_long ptb;             /* PFN of current level 1 page table */
        !           212:        u_long bim;             /* bootinfo magic */
        !           213:        u_long bip;             /* bootinfo pointer */
        !           214:        u_long biv;             /* bootinfo version */
        !           215: {
        !           216:        extern char kernel_text[], _end[];
        !           217:        struct mddt *mddtp;
        !           218:        struct mddt_cluster *memc;
        !           219:        int i, mddtweird;
        !           220:        struct vm_physseg *vps;
        !           221:        vaddr_t kernstart, kernend;
        !           222:        paddr_t kernstartpfn, kernendpfn, pfn0, pfn1;
        !           223:        vsize_t size;
        !           224:        char *p;
        !           225:        caddr_t v;
        !           226:        const char *bootinfo_msg;
        !           227:        const struct cpuinit *c;
        !           228:        extern caddr_t esym;
        !           229:        struct cpu_info *ci;
        !           230:        cpuid_t cpu_id;
        !           231:
        !           232:        /* NO OUTPUT ALLOWED UNTIL FURTHER NOTICE */
        !           233:
        !           234:        /*
        !           235:         * Turn off interrupts (not mchecks) and floating point.
        !           236:         * Make sure the instruction and data streams are consistent.
        !           237:         */
        !           238:        (void)alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH);
        !           239:        alpha_pal_wrfen(0);
        !           240:        ALPHA_TBIA();
        !           241:        alpha_pal_imb();
        !           242:
        !           243:        /* Initialize the SCB. */
        !           244:        scb_init();
        !           245:
        !           246:        cpu_id = cpu_number();
        !           247:
        !           248: #if defined(MULTIPROCESSOR)
        !           249:        /*
        !           250:         * Set our SysValue to the address of our cpu_info structure.
        !           251:         * Secondary processors do this in their spinup trampoline.
        !           252:         */
        !           253:        alpha_pal_wrval((u_long)&cpu_info[cpu_id]);
        !           254: #endif
        !           255:
        !           256:        ci = curcpu();
        !           257:        ci->ci_cpuid = cpu_id;
        !           258:
        !           259:        /*
        !           260:         * Get critical system information (if possible, from the
        !           261:         * information provided by the boot program).
        !           262:         */
        !           263:        bootinfo_msg = NULL;
        !           264:        if (bim == BOOTINFO_MAGIC) {
        !           265:                if (biv == 0) {         /* backward compat */
        !           266:                        biv = *(u_long *)bip;
        !           267:                        bip += 8;
        !           268:                }
        !           269:                switch (biv) {
        !           270:                case 1: {
        !           271:                        struct bootinfo_v1 *v1p = (struct bootinfo_v1 *)bip;
        !           272:
        !           273:                        bootinfo.ssym = v1p->ssym;
        !           274:                        bootinfo.esym = v1p->esym;
        !           275:                        /* hwrpb may not be provided by boot block in v1 */
        !           276:                        if (v1p->hwrpb != NULL) {
        !           277:                                bootinfo.hwrpb_phys =
        !           278:                                    ((struct rpb *)v1p->hwrpb)->rpb_phys;
        !           279:                                bootinfo.hwrpb_size = v1p->hwrpbsize;
        !           280:                        } else {
        !           281:                                bootinfo.hwrpb_phys =
        !           282:                                    ((struct rpb *)HWRPB_ADDR)->rpb_phys;
        !           283:                                bootinfo.hwrpb_size =
        !           284:                                    ((struct rpb *)HWRPB_ADDR)->rpb_size;
        !           285:                        }
        !           286:                        bcopy(v1p->boot_flags, bootinfo.boot_flags,
        !           287:                            min(sizeof v1p->boot_flags,
        !           288:                              sizeof bootinfo.boot_flags));
        !           289:                        bcopy(v1p->booted_kernel, bootinfo.booted_kernel,
        !           290:                            min(sizeof v1p->booted_kernel,
        !           291:                              sizeof bootinfo.booted_kernel));
        !           292:                        /* booted dev not provided in bootinfo */
        !           293:                        init_prom_interface((struct rpb *)
        !           294:                            ALPHA_PHYS_TO_K0SEG(bootinfo.hwrpb_phys));
        !           295:                        prom_getenv(PROM_E_BOOTED_DEV, bootinfo.booted_dev,
        !           296:                            sizeof bootinfo.booted_dev);
        !           297:                        break;
        !           298:                }
        !           299:                default:
        !           300:                        bootinfo_msg = "unknown bootinfo version";
        !           301:                        goto nobootinfo;
        !           302:                }
        !           303:        } else {
        !           304:                bootinfo_msg = "boot program did not pass bootinfo";
        !           305: nobootinfo:
        !           306:                bootinfo.ssym = (u_long)_end;
        !           307:                bootinfo.esym = (u_long)_end;
        !           308:                bootinfo.hwrpb_phys = ((struct rpb *)HWRPB_ADDR)->rpb_phys;
        !           309:                bootinfo.hwrpb_size = ((struct rpb *)HWRPB_ADDR)->rpb_size;
        !           310:                init_prom_interface((struct rpb *)HWRPB_ADDR);
        !           311:                prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo.boot_flags,
        !           312:                    sizeof bootinfo.boot_flags);
        !           313:                prom_getenv(PROM_E_BOOTED_FILE, bootinfo.booted_kernel,
        !           314:                    sizeof bootinfo.booted_kernel);
        !           315:                prom_getenv(PROM_E_BOOTED_DEV, bootinfo.booted_dev,
        !           316:                    sizeof bootinfo.booted_dev);
        !           317:        }
        !           318:
        !           319:        esym = (caddr_t)bootinfo.esym;
        !           320:        /*
        !           321:         * Initialize the kernel's mapping of the RPB.  It's needed for
        !           322:         * lots of things.
        !           323:         */
        !           324:        hwrpb = (struct rpb *)ALPHA_PHYS_TO_K0SEG(bootinfo.hwrpb_phys);
        !           325:
        !           326: #if defined(DEC_3000_300) || defined(DEC_3000_500)
        !           327:        if (hwrpb->rpb_type == ST_DEC_3000_300 ||
        !           328:            hwrpb->rpb_type == ST_DEC_3000_500) {
        !           329:                prom_getenv(PROM_E_SCSIID, dec_3000_scsiid,
        !           330:                    sizeof(dec_3000_scsiid));
        !           331:                prom_getenv(PROM_E_SCSIFAST, dec_3000_scsifast,
        !           332:                    sizeof(dec_3000_scsifast));
        !           333:        }
        !           334: #endif
        !           335:
        !           336:        /*
        !           337:         * Remember how many cycles there are per microsecond,
        !           338:         * so that we can use delay().  Round up, for safety.
        !           339:         */
        !           340:        cycles_per_usec = (hwrpb->rpb_cc_freq + 999999) / 1000000;
        !           341:
        !           342:        /*
        !           343:         * Initialize the (temporary) bootstrap console interface, so
        !           344:         * we can use printf until the VM system starts being setup.
        !           345:         * The real console is initialized before then.
        !           346:         */
        !           347:        init_bootstrap_console();
        !           348:
        !           349:        /* OUTPUT NOW ALLOWED */
        !           350:
        !           351:        /* delayed from above */
        !           352:        if (bootinfo_msg)
        !           353:                printf("WARNING: %s (0x%lx, 0x%lx, 0x%lx)\n",
        !           354:                    bootinfo_msg, bim, bip, biv);
        !           355:
        !           356:        /* Initialize the trap vectors on the primary processor. */
        !           357:        trap_init();
        !           358:
        !           359:        /*
        !           360:         * Find out what hardware we're on, and do basic initialization.
        !           361:         */
        !           362:        cputype = hwrpb->rpb_type;
        !           363:        if (cputype < 0) {
        !           364:                /*
        !           365:                 * At least some white-box systems have SRM which
        !           366:                 * reports a systype that's the negative of their
        !           367:                 * blue-box counterpart.
        !           368:                 */
        !           369:                cputype = -cputype;
        !           370:        }
        !           371:        c = platform_lookup(cputype);
        !           372:        if (c == NULL) {
        !           373:                platform_not_supported();
        !           374:                /* NOTREACHED */
        !           375:        }
        !           376:        (*c->init)();
        !           377:        strlcpy(cpu_model, platform.model, sizeof cpu_model);
        !           378:
        !           379:        /*
        !           380:         * Initialize the real console, so that the bootstrap console is
        !           381:         * no longer necessary.
        !           382:         */
        !           383:        (*platform.cons_init)();
        !           384:
        !           385: #if 0
        !           386:        /* Paranoid sanity checking */
        !           387:
        !           388:        assert(hwrpb->rpb_primary_cpu_id == alpha_pal_whami());
        !           389:
        !           390:        /*
        !           391:         * On single-CPU systypes, the primary should always be CPU 0,
        !           392:         * except on Alpha 8200 systems where the CPU id is related
        !           393:         * to the VID, which is related to the Turbo Laser node id.
        !           394:         */
        !           395:        if (cputype != ST_DEC_21000)
        !           396:                assert(hwrpb->rpb_primary_cpu_id == 0);
        !           397: #endif
        !           398:
        !           399:        /* NO MORE FIRMWARE ACCESS ALLOWED */
        !           400: #ifdef _PMAP_MAY_USE_PROM_CONSOLE
        !           401:        /*
        !           402:         * XXX (unless _PMAP_MAY_USE_PROM_CONSOLE is defined and
        !           403:         * XXX pmap_uses_prom_console() evaluates to non-zero.)
        !           404:         */
        !           405: #endif
        !           406:
        !           407: #ifndef SMALL_KERNEL
        !           408:        /*
        !           409:         * If we run on a BWX-capable processor, override cpu_switch
        !           410:         * with a faster version.
        !           411:         * We do this now because the kernel text might be mapped
        !           412:         * read-only eventually (although this is not the case at the moment).
        !           413:         */
        !           414:        if (alpha_implver() >= ALPHA_IMPLVER_EV5) {
        !           415:                if (~alpha_amask(ALPHA_AMASK_BWX) != 0) {
        !           416:                        extern vaddr_t __bwx_switch0, __bwx_switch1,
        !           417:                            __bwx_switch2, __bwx_switch3;
        !           418:                        u_int32_t *dst, *src, *end;
        !           419:
        !           420:                        src = (u_int32_t *)&__bwx_switch2;
        !           421:                        end = (u_int32_t *)&__bwx_switch3;
        !           422:                        dst = (u_int32_t *)&__bwx_switch0;
        !           423:                        while (src != end)
        !           424:                                *dst++ = *src++;
        !           425:                        src = (u_int32_t *)&__bwx_switch1;
        !           426:                        end = (u_int32_t *)&__bwx_switch2;
        !           427:                        while (src != end)
        !           428:                                *dst++ = *src++;
        !           429:                }
        !           430:        }
        !           431: #endif
        !           432:
        !           433:        /*
        !           434:         * find out this system's page size
        !           435:         */
        !           436:        if ((uvmexp.pagesize = hwrpb->rpb_page_size) != 8192)
        !           437:                panic("page size %d != 8192?!", uvmexp.pagesize);
        !           438:
        !           439:        uvm_setpagesize();
        !           440:
        !           441:        /*
        !           442:         * Find the beginning and end of the kernel (and leave a
        !           443:         * bit of space before the beginning for the bootstrap
        !           444:         * stack).
        !           445:         */
        !           446:        kernstart = trunc_page((vaddr_t)kernel_text) - 2 * PAGE_SIZE;
        !           447:        kernend = (vaddr_t)round_page((vaddr_t)bootinfo.esym);
        !           448:
        !           449:        kernstartpfn = atop(ALPHA_K0SEG_TO_PHYS(kernstart));
        !           450:        kernendpfn = atop(ALPHA_K0SEG_TO_PHYS(kernend));
        !           451:
        !           452:        /*
        !           453:         * Find out how much memory is available, by looking at
        !           454:         * the memory cluster descriptors.  This also tries to do
        !           455:         * its best to detect things things that have never been seen
        !           456:         * before...
        !           457:         */
        !           458:        mddtp = (struct mddt *)(((caddr_t)hwrpb) + hwrpb->rpb_memdat_off);
        !           459:
        !           460:        /* MDDT SANITY CHECKING */
        !           461:        mddtweird = 0;
        !           462:        if (mddtp->mddt_cluster_cnt < 2) {
        !           463:                mddtweird = 1;
        !           464:                printf("WARNING: weird number of mem clusters: %lu\n",
        !           465:                    mddtp->mddt_cluster_cnt);
        !           466:        }
        !           467:
        !           468: #if 0
        !           469:        printf("Memory cluster count: %d\n", mddtp->mddt_cluster_cnt);
        !           470: #endif
        !           471:
        !           472:        for (i = 0; i < mddtp->mddt_cluster_cnt; i++) {
        !           473:                memc = &mddtp->mddt_clusters[i];
        !           474: #if 0
        !           475:                printf("MEMC %d: pfn 0x%lx cnt 0x%lx usage 0x%lx\n", i,
        !           476:                    memc->mddt_pfn, memc->mddt_pg_cnt, memc->mddt_usage);
        !           477: #endif
        !           478:                totalphysmem += memc->mddt_pg_cnt;
        !           479:                if (mem_cluster_cnt < VM_PHYSSEG_MAX) { /* XXX */
        !           480:                        mem_clusters[mem_cluster_cnt].start =
        !           481:                            ptoa(memc->mddt_pfn);
        !           482:                        mem_clusters[mem_cluster_cnt].size =
        !           483:                            ptoa(memc->mddt_pg_cnt);
        !           484:                        if (memc->mddt_usage & MDDT_mbz ||
        !           485:                            memc->mddt_usage & MDDT_NONVOLATILE || /* XXX */
        !           486:                            memc->mddt_usage & MDDT_PALCODE)
        !           487:                                mem_clusters[mem_cluster_cnt].size |=
        !           488:                                    VM_PROT_READ;
        !           489:                        else
        !           490:                                mem_clusters[mem_cluster_cnt].size |=
        !           491:                                    VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
        !           492:                        mem_cluster_cnt++;
        !           493:                } /* XXX else print something! */
        !           494:
        !           495:                if (memc->mddt_usage & MDDT_mbz) {
        !           496:                        mddtweird = 1;
        !           497:                        printf("WARNING: mem cluster %d has weird "
        !           498:                            "usage 0x%lx\n", i, memc->mddt_usage);
        !           499:                        unknownmem += memc->mddt_pg_cnt;
        !           500:                        continue;
        !           501:                }
        !           502:                if (memc->mddt_usage & MDDT_NONVOLATILE) {
        !           503:                        /* XXX should handle these... */
        !           504:                        printf("WARNING: skipping non-volatile mem "
        !           505:                            "cluster %d\n", i);
        !           506:                        unusedmem += memc->mddt_pg_cnt;
        !           507:                        continue;
        !           508:                }
        !           509:                if (memc->mddt_usage & MDDT_PALCODE) {
        !           510:                        resvmem += memc->mddt_pg_cnt;
        !           511:                        continue;
        !           512:                }
        !           513:
        !           514:                /*
        !           515:                 * We have a memory cluster available for system
        !           516:                 * software use.  We must determine if this cluster
        !           517:                 * holds the kernel.
        !           518:                 */
        !           519: #ifdef _PMAP_MAY_USE_PROM_CONSOLE
        !           520:                /*
        !           521:                 * XXX If the kernel uses the PROM console, we only use the
        !           522:                 * XXX memory after the kernel in the first system segment,
        !           523:                 * XXX to avoid clobbering prom mapping, data, etc.
        !           524:                 */
        !           525:            if (!pmap_uses_prom_console() || physmem == 0) {
        !           526: #endif /* _PMAP_MAY_USE_PROM_CONSOLE */
        !           527:                physmem += memc->mddt_pg_cnt;
        !           528:                pfn0 = memc->mddt_pfn;
        !           529:                pfn1 = memc->mddt_pfn + memc->mddt_pg_cnt;
        !           530:                if (pfn0 <= kernstartpfn && kernendpfn <= pfn1) {
        !           531:                        /*
        !           532:                         * Must compute the location of the kernel
        !           533:                         * within the segment.
        !           534:                         */
        !           535: #if 0
        !           536:                        printf("Cluster %d contains kernel\n", i);
        !           537: #endif
        !           538: #ifdef _PMAP_MAY_USE_PROM_CONSOLE
        !           539:                    if (!pmap_uses_prom_console()) {
        !           540: #endif /* _PMAP_MAY_USE_PROM_CONSOLE */
        !           541:                        if (pfn0 < kernstartpfn) {
        !           542:                                /*
        !           543:                                 * There is a chunk before the kernel.
        !           544:                                 */
        !           545: #if 0
        !           546:                                printf("Loading chunk before kernel: "
        !           547:                                    "0x%lx / 0x%lx\n", pfn0, kernstartpfn);
        !           548: #endif
        !           549:                                uvm_page_physload(pfn0, kernstartpfn,
        !           550:                                    pfn0, kernstartpfn, VM_FREELIST_DEFAULT);
        !           551:                        }
        !           552: #ifdef _PMAP_MAY_USE_PROM_CONSOLE
        !           553:                    }
        !           554: #endif /* _PMAP_MAY_USE_PROM_CONSOLE */
        !           555:                        if (kernendpfn < pfn1) {
        !           556:                                /*
        !           557:                                 * There is a chunk after the kernel.
        !           558:                                 */
        !           559: #if 0
        !           560:                                printf("Loading chunk after kernel: "
        !           561:                                    "0x%lx / 0x%lx\n", kernendpfn, pfn1);
        !           562: #endif
        !           563:                                uvm_page_physload(kernendpfn, pfn1,
        !           564:                                    kernendpfn, pfn1, VM_FREELIST_DEFAULT);
        !           565:                        }
        !           566:                } else {
        !           567:                        /*
        !           568:                         * Just load this cluster as one chunk.
        !           569:                         */
        !           570: #if 0
        !           571:                        printf("Loading cluster %d: 0x%lx / 0x%lx\n", i,
        !           572:                            pfn0, pfn1);
        !           573: #endif
        !           574:                        uvm_page_physload(pfn0, pfn1, pfn0, pfn1,
        !           575:                            VM_FREELIST_DEFAULT);
        !           576:                }
        !           577: #ifdef _PMAP_MAY_USE_PROM_CONSOLE
        !           578:            }
        !           579: #endif /* _PMAP_MAY_USE_PROM_CONSOLE */
        !           580:        }
        !           581:
        !           582: #ifdef DEBUG
        !           583:        /*
        !           584:         * Dump out the MDDT if it looks odd...
        !           585:         */
        !           586:        if (mddtweird) {
        !           587:                printf("\n");
        !           588:                printf("complete memory cluster information:\n");
        !           589:                for (i = 0; i < mddtp->mddt_cluster_cnt; i++) {
        !           590:                        printf("mddt %d:\n", i);
        !           591:                        printf("\tpfn %lx\n",
        !           592:                            mddtp->mddt_clusters[i].mddt_pfn);
        !           593:                        printf("\tcnt %lx\n",
        !           594:                            mddtp->mddt_clusters[i].mddt_pg_cnt);
        !           595:                        printf("\ttest %lx\n",
        !           596:                            mddtp->mddt_clusters[i].mddt_pg_test);
        !           597:                        printf("\tbva %lx\n",
        !           598:                            mddtp->mddt_clusters[i].mddt_v_bitaddr);
        !           599:                        printf("\tbpa %lx\n",
        !           600:                            mddtp->mddt_clusters[i].mddt_p_bitaddr);
        !           601:                        printf("\tbcksum %lx\n",
        !           602:                            mddtp->mddt_clusters[i].mddt_bit_cksum);
        !           603:                        printf("\tusage %lx\n",
        !           604:                            mddtp->mddt_clusters[i].mddt_usage);
        !           605:                }
        !           606:                printf("\n");
        !           607:        }
        !           608: #endif
        !           609:
        !           610:        if (totalphysmem == 0)
        !           611:                panic("can't happen: system seems to have no memory!");
        !           612: #if 0
        !           613:        printf("totalphysmem = %u\n", totalphysmem);
        !           614:        printf("physmem = %u\n", physmem);
        !           615:        printf("resvmem = %d\n", resvmem);
        !           616:        printf("unusedmem = %d\n", unusedmem);
        !           617:        printf("unknownmem = %d\n", unknownmem);
        !           618: #endif
        !           619:
        !           620:        /*
        !           621:         * Initialize error message buffer (at end of core).
        !           622:         */
        !           623:        {
        !           624:                vsize_t sz = (vsize_t)round_page(MSGBUFSIZE);
        !           625:                vsize_t reqsz = sz;
        !           626:
        !           627:                vps = &vm_physmem[vm_nphysseg - 1];
        !           628:
        !           629:                /* shrink so that it'll fit in the last segment */
        !           630:                if ((vps->avail_end - vps->avail_start) < atop(sz))
        !           631:                        sz = ptoa(vps->avail_end - vps->avail_start);
        !           632:
        !           633:                vps->end -= atop(sz);
        !           634:                vps->avail_end -= atop(sz);
        !           635:                initmsgbuf((caddr_t) ALPHA_PHYS_TO_K0SEG(ptoa(vps->end)), sz);
        !           636:
        !           637:                /* Remove the last segment if it now has no pages. */
        !           638:                if (vps->start == vps->end)
        !           639:                        vm_nphysseg--;
        !           640:
        !           641:                /* warn if the message buffer had to be shrunk */
        !           642:                if (sz != reqsz)
        !           643:                        printf("WARNING: %ld bytes not available for msgbuf "
        !           644:                            "in last cluster (%ld used)\n", reqsz, sz);
        !           645:
        !           646:        }
        !           647:
        !           648:        /*
        !           649:         * Init mapping for u page(s) for proc 0
        !           650:         */
        !           651:        proc0.p_addr = proc0paddr =
        !           652:            (struct user *)pmap_steal_memory(UPAGES * PAGE_SIZE, NULL, NULL);
        !           653:
        !           654:        /*
        !           655:         * Allocate space for system data structures.  These data structures
        !           656:         * are allocated here instead of cpu_startup() because physical
        !           657:         * memory is directly addressable.  We don't have to map these into
        !           658:         * virtual address space.
        !           659:         */
        !           660:        size = (vsize_t)allocsys(NULL);
        !           661:        v = (caddr_t)pmap_steal_memory(size, NULL, NULL);
        !           662:        if ((allocsys(v) - v) != size)
        !           663:                panic("alpha_init: table size inconsistency");
        !           664:
        !           665:        /*
        !           666:         * Clear allocated memory.
        !           667:         */
        !           668:        bzero(v, size);
        !           669:
        !           670:        /*
        !           671:         * Initialize the virtual memory system, and set the
        !           672:         * page table base register in proc 0's PCB.
        !           673:         */
        !           674:        pmap_bootstrap(ALPHA_PHYS_TO_K0SEG(ptb << PGSHIFT),
        !           675:            hwrpb->rpb_max_asn, hwrpb->rpb_pcs_cnt);
        !           676:
        !           677:        /*
        !           678:         * Initialize the rest of proc 0's PCB, and cache its physical
        !           679:         * address.
        !           680:         */
        !           681:        proc0.p_md.md_pcbpaddr =
        !           682:            (struct pcb *)ALPHA_K0SEG_TO_PHYS((vaddr_t)&proc0paddr->u_pcb);
        !           683:
        !           684:        /*
        !           685:         * Set the kernel sp, reserving space for an (empty) trapframe,
        !           686:         * and make proc0's trapframe pointer point to it for sanity.
        !           687:         */
        !           688:        proc0paddr->u_pcb.pcb_hw.apcb_ksp =
        !           689:            (u_int64_t)proc0paddr + USPACE - sizeof(struct trapframe);
        !           690:        proc0.p_md.md_tf =
        !           691:            (struct trapframe *)proc0paddr->u_pcb.pcb_hw.apcb_ksp;
        !           692:
        !           693:        /*
        !           694:         * Initialize the primary CPU's idle PCB to proc0's.  In a
        !           695:         * MULTIPROCESSOR configuration, each CPU will later get
        !           696:         * its own idle PCB when autoconfiguration runs.
        !           697:         */
        !           698:        ci->ci_idle_pcb = &proc0paddr->u_pcb;
        !           699:        ci->ci_idle_pcb_paddr = (u_long)proc0.p_md.md_pcbpaddr;
        !           700:
        !           701:        /*
        !           702:         * Look at arguments passed to us and compute boothowto.
        !           703:         */
        !           704:
        !           705: #ifdef KADB
        !           706:        boothowto |= RB_KDB;
        !           707: #endif
        !           708:        for (p = bootinfo.boot_flags; p && *p != '\0'; p++) {
        !           709:                /*
        !           710:                 * Note that we'd really like to differentiate case here,
        !           711:                 * but the Alpha AXP Architecture Reference Manual
        !           712:                 * says that we shouldn't.
        !           713:                 */
        !           714:                switch (*p) {
        !           715:                case 'a': /* Ignore */
        !           716:                case 'A':
        !           717:                        break;
        !           718:
        !           719:                case 'b': /* Enter DDB as soon as the console is initialised */
        !           720:                case 'B':
        !           721:                        boothowto |= RB_KDB;
        !           722:                        break;
        !           723:
        !           724:                case 'c': /* enter user kernel configuration */
        !           725:                case 'C':
        !           726:                        boothowto |= RB_CONFIG;
        !           727:                        break;
        !           728:
        !           729: #ifdef DEBUG
        !           730:                case 'd': /* crash dump immediately after autoconfig */
        !           731:                case 'D':
        !           732:                        boothowto |= RB_DUMP;
        !           733:                        break;
        !           734: #endif
        !           735:
        !           736:                case 'h': /* always halt, never reboot */
        !           737:                case 'H':
        !           738:                        boothowto |= RB_HALT;
        !           739:                        break;
        !           740:
        !           741: #if 0
        !           742:                case 'm': /* mini root present in memory */
        !           743:                case 'M':
        !           744:                        boothowto |= RB_MINIROOT;
        !           745:                        break;
        !           746: #endif
        !           747:
        !           748:                case 'n': /* askname */
        !           749:                case 'N':
        !           750:                        boothowto |= RB_ASKNAME;
        !           751:                        break;
        !           752:
        !           753:                case 's': /* single-user */
        !           754:                case 'S':
        !           755:                        boothowto |= RB_SINGLE;
        !           756:                        break;
        !           757:
        !           758:                case '-':
        !           759:                        /*
        !           760:                         * Just ignore this.  It's not required, but it's
        !           761:                         * common for it to be passed regardless.
        !           762:                         */
        !           763:                        break;
        !           764:
        !           765:                default:
        !           766:                        printf("Unrecognized boot flag '%c'.\n", *p);
        !           767:                        break;
        !           768:                }
        !           769:        }
        !           770:
        !           771:
        !           772:        /*
        !           773:         * Figure out the number of cpus in the box, from RPB fields.
        !           774:         * Really.  We mean it.
        !           775:         */
        !           776:        for (alpha_cpus = 0, i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
        !           777:                struct pcs *pcsp;
        !           778:
        !           779:                pcsp = LOCATE_PCS(hwrpb, i);
        !           780:                if ((pcsp->pcs_flags & PCS_PP) != 0)
        !           781:                        alpha_cpus++;
        !           782:        }
        !           783:
        !           784:        /*
        !           785:         * Initialize debuggers, and break into them if appropriate.
        !           786:         */
        !           787: #ifdef DDB
        !           788:        ddb_init();
        !           789:
        !           790:        if (boothowto & RB_KDB)
        !           791:                Debugger();
        !           792: #endif
        !           793: #ifdef KGDB
        !           794:        if (boothowto & RB_KDB)
        !           795:                kgdb_connect(0);
        !           796: #endif
        !           797:        /*
        !           798:         * Figure out our clock frequency, from RPB fields.
        !           799:         */
        !           800:        hz = hwrpb->rpb_intr_freq >> 12;
        !           801:        if (!(60 <= hz && hz <= 10240)) {
        !           802:                hz = 1024;
        !           803: #ifdef DIAGNOSTIC
        !           804:                printf("WARNING: unbelievable rpb_intr_freq: %ld (%d hz)\n",
        !           805:                        hwrpb->rpb_intr_freq, hz);
        !           806: #endif
        !           807:        }
        !           808: }
        !           809:
        !           810: caddr_t
        !           811: allocsys(v)
        !           812:        caddr_t v;
        !           813: {
        !           814:        /*
        !           815:         * Allocate space for system data structures.
        !           816:         * The first available kernel virtual address is in "v".
        !           817:         * As pages of kernel virtual memory are allocated, "v" is incremented.
        !           818:         *
        !           819:         * These data structures are allocated here instead of cpu_startup()
        !           820:         * because physical memory is directly addressable. We don't have
        !           821:         * to map these into virtual address space.
        !           822:         */
        !           823: #define valloc(name, type, num) \
        !           824:            (name) = (type *)v; v = (caddr_t)ALIGN((name)+(num))
        !           825:
        !           826: #ifdef SYSVMSG
        !           827:        valloc(msgpool, char, msginfo.msgmax);
        !           828:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
        !           829:        valloc(msghdrs, struct msg, msginfo.msgtql);
        !           830:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
        !           831: #endif
        !           832:
        !           833: #undef valloc
        !           834:
        !           835:        return v;
        !           836: }
        !           837:
        !           838: void
        !           839: consinit()
        !           840: {
        !           841:
        !           842:        /*
        !           843:         * Everything related to console initialization is done
        !           844:         * in alpha_init().
        !           845:         */
        !           846: #if defined(DIAGNOSTIC) && defined(_PMAP_MAY_USE_PROM_CONSOLE)
        !           847:        printf("consinit: %susing prom console\n",
        !           848:            pmap_uses_prom_console() ? "" : "not ");
        !           849: #endif
        !           850: }
        !           851:
        !           852: void
        !           853: cpu_startup()
        !           854: {
        !           855:        vaddr_t minaddr, maxaddr;
        !           856: #if defined(DEBUG)
        !           857:        extern int pmapdebug;
        !           858:        int opmapdebug = pmapdebug;
        !           859:
        !           860:        pmapdebug = 0;
        !           861: #endif
        !           862:
        !           863:        /*
        !           864:         * Good {morning,afternoon,evening,night}.
        !           865:         */
        !           866:        printf(version);
        !           867:        identifycpu();
        !           868:        printf("total memory = %ld (%ldK)\n", ptoa((u_long)totalphysmem),
        !           869:            ptoa((u_long)totalphysmem) / 1024);
        !           870:        printf("(%ld reserved for PROM, ", ptoa((u_long)resvmem));
        !           871:        printf("%ld used by OpenBSD)\n", ptoa((u_long)physmem));
        !           872:        if (unusedmem) {
        !           873:                printf("WARNING: unused memory = %ld (%ldK)\n",
        !           874:                    ptoa((u_long)unusedmem), ptoa((u_long)unusedmem) / 1024);
        !           875:        }
        !           876:        if (unknownmem) {
        !           877:                printf("WARNING: %ld (%ldK) of memory with unknown purpose\n",
        !           878:                    ptoa((u_long)unknownmem), ptoa((u_long)unknownmem) / 1024);
        !           879:        }
        !           880:
        !           881:        /*
        !           882:         * Determine how many buffers to allocate.
        !           883:         * We allocate bufcachepercent% of memory for buffer space.
        !           884:         */
        !           885:        if (bufpages == 0)
        !           886:                bufpages = physmem * bufcachepercent / 100;
        !           887:
        !           888:        /*
        !           889:         * Allocate a submap for exec arguments.  This map effectively
        !           890:         * limits the number of processes exec'ing at any time.
        !           891:         */
        !           892:        minaddr = vm_map_min(kernel_map);
        !           893:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           894:            16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
        !           895:
        !           896:        /*
        !           897:         * Allocate a submap for physio
        !           898:         */
        !           899:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           900:            VM_PHYS_SIZE, 0, FALSE, NULL);
        !           901:
        !           902: #if defined(DEBUG)
        !           903:        pmapdebug = opmapdebug;
        !           904: #endif
        !           905:        printf("avail memory = %ld (%ldK)\n", (long)ptoa(uvmexp.free),
        !           906:            (long)ptoa(uvmexp.free) / 1024);
        !           907: #if 0
        !           908:        {
        !           909:                extern u_long pmap_pages_stolen;
        !           910:
        !           911:                printf("stolen memory for VM structures = %d\n", pmap_pages_stolen * PAGE_SIZE);
        !           912:        }
        !           913: #endif
        !           914:
        !           915:        /*
        !           916:         * Set up buffers, so they can be used to read disk labels.
        !           917:         */
        !           918:        bufinit();
        !           919:
        !           920:        /*
        !           921:         * Configure the system.
        !           922:         */
        !           923:        if (boothowto & RB_CONFIG) {
        !           924: #ifdef BOOT_CONFIG
        !           925:                user_config();
        !           926: #else
        !           927:                printf("kernel does not support -c; continuing..\n");
        !           928: #endif
        !           929:        }
        !           930:
        !           931:        /*
        !           932:         * Set up the HWPCB so that it's safe to configure secondary
        !           933:         * CPUs.
        !           934:         */
        !           935:        hwrpb_primary_init();
        !           936: }
        !           937:
        !           938: /*
        !           939:  * Retrieve the platform name from the DSR.
        !           940:  */
        !           941: const char *
        !           942: alpha_dsr_sysname()
        !           943: {
        !           944:        struct dsrdb *dsr;
        !           945:        const char *sysname;
        !           946:
        !           947:        /*
        !           948:         * DSR does not exist on early HWRPB versions.
        !           949:         */
        !           950:        if (hwrpb->rpb_version < HWRPB_DSRDB_MINVERS)
        !           951:                return (NULL);
        !           952:
        !           953:        dsr = (struct dsrdb *)(((caddr_t)hwrpb) + hwrpb->rpb_dsrdb_off);
        !           954:        sysname = (const char *)((caddr_t)dsr + (dsr->dsr_sysname_off +
        !           955:            sizeof(u_int64_t)));
        !           956:        return (sysname);
        !           957: }
        !           958:
        !           959: /*
        !           960:  * Lookup the system specified system variation in the provided table,
        !           961:  * returning the model string on match.
        !           962:  */
        !           963: const char *
        !           964: alpha_variation_name(variation, avtp)
        !           965:        u_int64_t variation;
        !           966:        const struct alpha_variation_table *avtp;
        !           967: {
        !           968:        int i;
        !           969:
        !           970:        for (i = 0; avtp[i].avt_model != NULL; i++)
        !           971:                if (avtp[i].avt_variation == variation)
        !           972:                        return (avtp[i].avt_model);
        !           973:        return (NULL);
        !           974: }
        !           975:
        !           976: /*
        !           977:  * Generate a default platform name based for unknown system variations.
        !           978:  */
        !           979: const char *
        !           980: alpha_unknown_sysname()
        !           981: {
        !           982:        static char s[128];             /* safe size */
        !           983:
        !           984:        snprintf(s, sizeof s, "%s family, unknown model variation 0x%lx",
        !           985:            platform.family, hwrpb->rpb_variation & SV_ST_MASK);
        !           986:        return ((const char *)s);
        !           987: }
        !           988:
        !           989: void
        !           990: identifycpu()
        !           991: {
        !           992:        char *s;
        !           993:        int slen;
        !           994:
        !           995:        /*
        !           996:         * print out CPU identification information.
        !           997:         */
        !           998:        printf("%s", cpu_model);
        !           999:        for(s = cpu_model; *s; ++s)
        !          1000:                if(strncasecmp(s, "MHz", 3) == 0)
        !          1001:                        goto skipMHz;
        !          1002:        printf(", %ldMHz", hwrpb->rpb_cc_freq / 1000000);
        !          1003: skipMHz:
        !          1004:        /* fill in hw_serial if a serial number is known */
        !          1005:        slen = strlen(hwrpb->rpb_ssn) + 1;
        !          1006:        if (slen > 1) {
        !          1007:                hw_serial = malloc(slen, M_SYSCTL, M_NOWAIT);
        !          1008:                if (hw_serial)
        !          1009:                        strlcpy(hw_serial, (char *)hwrpb->rpb_ssn, slen);
        !          1010:        }
        !          1011:
        !          1012:        printf("\n");
        !          1013:        printf("%ld byte page size, %d processor%s.\n",
        !          1014:            hwrpb->rpb_page_size, alpha_cpus, alpha_cpus == 1 ? "" : "s");
        !          1015: #if 0
        !          1016:        /* this is not particularly useful! */
        !          1017:        printf("variation: 0x%lx, revision 0x%lx\n",
        !          1018:            hwrpb->rpb_variation, *(long *)hwrpb->rpb_revision);
        !          1019: #endif
        !          1020: }
        !          1021:
        !          1022: int    waittime = -1;
        !          1023: struct pcb dumppcb;
        !          1024:
        !          1025: void
        !          1026: boot(howto)
        !          1027:        int howto;
        !          1028: {
        !          1029: #if defined(MULTIPROCESSOR)
        !          1030: #if 0 /* XXX See below. */
        !          1031:        u_long cpu_id;
        !          1032: #endif
        !          1033: #endif
        !          1034:
        !          1035: #if defined(MULTIPROCESSOR)
        !          1036:        /* We must be running on the primary CPU. */
        !          1037:        if (alpha_pal_whami() != hwrpb->rpb_primary_cpu_id)
        !          1038:                panic("cpu_reboot: not on primary CPU!");
        !          1039: #endif
        !          1040:
        !          1041:        /* If system is cold, just halt. */
        !          1042:        if (cold) {
        !          1043:                /* (Unless the user explicitly asked for reboot.) */
        !          1044:                if ((howto & RB_USERREQ) == 0)
        !          1045:                        howto |= RB_HALT;
        !          1046:                goto haltsys;
        !          1047:        }
        !          1048:
        !          1049:        /* If "always halt" was specified as a boot flag, obey. */
        !          1050:        if ((boothowto & RB_HALT) != 0)
        !          1051:                howto |= RB_HALT;
        !          1052:
        !          1053:        boothowto = howto;
        !          1054:        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
        !          1055:                waittime = 0;
        !          1056:                vfs_shutdown();
        !          1057:                /*
        !          1058:                 * If we've been adjusting the clock, the todr
        !          1059:                 * will be out of synch; adjust it now unless
        !          1060:                 * the system has been sitting in ddb.
        !          1061:                 */
        !          1062:                if ((howto & RB_TIMEBAD) == 0) {
        !          1063:                        resettodr();
        !          1064:                } else {
        !          1065:                        printf("WARNING: not updating battery clock\n");
        !          1066:                }
        !          1067:        }
        !          1068:
        !          1069:        /* Disable interrupts. */
        !          1070:        splhigh();
        !          1071:
        !          1072:        /* If rebooting and a dump is requested do it. */
        !          1073:        if (howto & RB_DUMP)
        !          1074:                dumpsys();
        !          1075:
        !          1076: haltsys:
        !          1077:
        !          1078:        /* run any shutdown hooks */
        !          1079:        doshutdownhooks();
        !          1080:
        !          1081: #if defined(MULTIPROCESSOR)
        !          1082: #if 0 /* XXX doesn't work when called from here?! */
        !          1083:        /* Kill off any secondary CPUs. */
        !          1084:        for (cpu_id = 0; cpu_id < hwrpb->rpb_pcs_cnt; cpu_id++) {
        !          1085:                if (cpu_id == hwrpb->rpb_primary_cpu_id ||
        !          1086:                    cpu_info[cpu_id].ci_softc == NULL)
        !          1087:                        continue;
        !          1088:                cpu_halt_secondary(cpu_id);
        !          1089:        }
        !          1090: #endif
        !          1091: #endif
        !          1092:
        !          1093: #ifdef BOOTKEY
        !          1094:        printf("hit any key to %s...\n", howto & RB_HALT ? "halt" : "reboot");
        !          1095:        cnpollc(1);     /* for proper keyboard command handling */
        !          1096:        cngetc();
        !          1097:        cnpollc(0);
        !          1098:        printf("\n");
        !          1099: #endif
        !          1100:
        !          1101:        /* Finally, powerdown/halt/reboot the system. */
        !          1102:        if ((howto & RB_POWERDOWN) == RB_POWERDOWN &&
        !          1103:            platform.powerdown != NULL) {
        !          1104:                (*platform.powerdown)();
        !          1105:                printf("WARNING: powerdown failed!\n");
        !          1106:        }
        !          1107:        printf("%s\n\n", howto & RB_HALT ? "halted." : "rebooting...");
        !          1108:        prom_halt(howto & RB_HALT);
        !          1109:        /*NOTREACHED*/
        !          1110: }
        !          1111:
        !          1112: /*
        !          1113:  * These variables are needed by /sbin/savecore
        !          1114:  */
        !          1115: u_long dumpmag = 0x8fca0101;   /* magic number */
        !          1116: int    dumpsize = 0;           /* pages */
        !          1117: long   dumplo = 0;             /* blocks */
        !          1118:
        !          1119: /*
        !          1120:  * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers.
        !          1121:  */
        !          1122: int
        !          1123: cpu_dumpsize()
        !          1124: {
        !          1125:        int size;
        !          1126:
        !          1127:        size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)) +
        !          1128:            ALIGN(mem_cluster_cnt * sizeof(phys_ram_seg_t));
        !          1129:        if (roundup(size, dbtob(1)) != dbtob(1))
        !          1130:                return -1;
        !          1131:
        !          1132:        return (1);
        !          1133: }
        !          1134:
        !          1135: /*
        !          1136:  * cpu_dump_mempagecnt: calculate size of RAM (in pages) to be dumped.
        !          1137:  */
        !          1138: u_long
        !          1139: cpu_dump_mempagecnt()
        !          1140: {
        !          1141:        u_long i, n;
        !          1142:
        !          1143:        n = 0;
        !          1144:        for (i = 0; i < mem_cluster_cnt; i++)
        !          1145:                n += atop(mem_clusters[i].size);
        !          1146:        return (n);
        !          1147: }
        !          1148:
        !          1149: /*
        !          1150:  * cpu_dump: dump machine-dependent kernel core dump headers.
        !          1151:  */
        !          1152: int
        !          1153: cpu_dump()
        !          1154: {
        !          1155:        int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
        !          1156:        char buf[dbtob(1)];
        !          1157:        kcore_seg_t *segp;
        !          1158:        cpu_kcore_hdr_t *cpuhdrp;
        !          1159:        phys_ram_seg_t *memsegp;
        !          1160:        int i;
        !          1161:
        !          1162:        dump = bdevsw[major(dumpdev)].d_dump;
        !          1163:
        !          1164:        bzero(buf, sizeof buf);
        !          1165:        segp = (kcore_seg_t *)buf;
        !          1166:        cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp))];
        !          1167:        memsegp = (phys_ram_seg_t *)&buf[ALIGN(sizeof(*segp)) +
        !          1168:            ALIGN(sizeof(*cpuhdrp))];
        !          1169:
        !          1170:        /*
        !          1171:         * Generate a segment header.
        !          1172:         */
        !          1173:        CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
        !          1174:        segp->c_size = dbtob(1) - ALIGN(sizeof(*segp));
        !          1175:
        !          1176:        /*
        !          1177:         * Add the machine-dependent header info.
        !          1178:         */
        !          1179:        cpuhdrp->lev1map_pa = ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map);
        !          1180:        cpuhdrp->page_size = PAGE_SIZE;
        !          1181:        cpuhdrp->nmemsegs = mem_cluster_cnt;
        !          1182:
        !          1183:        /*
        !          1184:         * Fill in the memory segment descriptors.
        !          1185:         */
        !          1186:        for (i = 0; i < mem_cluster_cnt; i++) {
        !          1187:                memsegp[i].start = mem_clusters[i].start;
        !          1188:                memsegp[i].size = mem_clusters[i].size & ~PAGE_MASK;
        !          1189:        }
        !          1190:
        !          1191:        return (dump(dumpdev, dumplo, (caddr_t)buf, dbtob(1)));
        !          1192: }
        !          1193:
        !          1194: /*
        !          1195:  * This is called by main to set dumplo and dumpsize.
        !          1196:  * Dumps always skip the first PAGE_SIZE of disk space
        !          1197:  * in case there might be a disk label stored there.
        !          1198:  * If there is extra space, put dump at the end to
        !          1199:  * reduce the chance that swapping trashes it.
        !          1200:  */
        !          1201: void
        !          1202: dumpconf(void)
        !          1203: {
        !          1204:        int nblks, dumpblks;    /* size of dump area */
        !          1205:
        !          1206:        if (dumpdev == NODEV ||
        !          1207:            (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
        !          1208:                return;
        !          1209:        if (nblks <= ctod(1))
        !          1210:                return;
        !          1211:
        !          1212:        dumpblks = cpu_dumpsize();
        !          1213:        if (dumpblks < 0)
        !          1214:                return;
        !          1215:        dumpblks += ctod(cpu_dump_mempagecnt());
        !          1216:
        !          1217:        /* If dump won't fit (incl. room for possible label), punt. */
        !          1218:        if (dumpblks > (nblks - ctod(1)))
        !          1219:                return;
        !          1220:
        !          1221:        /* Put dump at end of partition */
        !          1222:        dumplo = nblks - dumpblks;
        !          1223:
        !          1224:        /* dumpsize is in page units, and doesn't include headers. */
        !          1225:        dumpsize = cpu_dump_mempagecnt();
        !          1226: }
        !          1227:
        !          1228: /*
        !          1229:  * Dump the kernel's image to the swap partition.
        !          1230:  */
        !          1231: #define        BYTES_PER_DUMP  PAGE_SIZE
        !          1232:
        !          1233: void
        !          1234: dumpsys()
        !          1235: {
        !          1236:        u_long totalbytesleft, bytes, i, n, memcl;
        !          1237:        u_long maddr;
        !          1238:        int psize;
        !          1239:        daddr64_t blkno;
        !          1240:        int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
        !          1241:        int error;
        !          1242:        extern int msgbufmapped;
        !          1243:
        !          1244:        /* Save registers. */
        !          1245:        savectx(&dumppcb);
        !          1246:
        !          1247:        msgbufmapped = 0;       /* don't record dump msgs in msgbuf */
        !          1248:        if (dumpdev == NODEV)
        !          1249:                return;
        !          1250:
        !          1251:        /*
        !          1252:         * For dumps during autoconfiguration,
        !          1253:         * if dump device has already configured...
        !          1254:         */
        !          1255:        if (dumpsize == 0)
        !          1256:                dumpconf();
        !          1257:        if (dumplo <= 0) {
        !          1258:                printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
        !          1259:                    minor(dumpdev));
        !          1260:                return;
        !          1261:        }
        !          1262:        printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
        !          1263:            minor(dumpdev), dumplo);
        !          1264:
        !          1265:        psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
        !          1266:        printf("dump ");
        !          1267:        if (psize == -1) {
        !          1268:                printf("area unavailable\n");
        !          1269:                return;
        !          1270:        }
        !          1271:
        !          1272:        /* XXX should purge all outstanding keystrokes. */
        !          1273:
        !          1274:        if ((error = cpu_dump()) != 0)
        !          1275:                goto err;
        !          1276:
        !          1277:        totalbytesleft = ptoa(cpu_dump_mempagecnt());
        !          1278:        blkno = dumplo + cpu_dumpsize();
        !          1279:        dump = bdevsw[major(dumpdev)].d_dump;
        !          1280:        error = 0;
        !          1281:
        !          1282:        for (memcl = 0; memcl < mem_cluster_cnt; memcl++) {
        !          1283:                maddr = mem_clusters[memcl].start;
        !          1284:                bytes = mem_clusters[memcl].size & ~PAGE_MASK;
        !          1285:
        !          1286:                for (i = 0; i < bytes; i += n, totalbytesleft -= n) {
        !          1287:
        !          1288:                        /* Print out how many MBs we to go. */
        !          1289:                        if ((totalbytesleft % (1024*1024)) == 0)
        !          1290:                                printf("%ld ", totalbytesleft / (1024 * 1024));
        !          1291:
        !          1292:                        /* Limit size for next transfer. */
        !          1293:                        n = bytes - i;
        !          1294:                        if (n > BYTES_PER_DUMP)
        !          1295:                                n =  BYTES_PER_DUMP;
        !          1296:
        !          1297:                        error = (*dump)(dumpdev, blkno,
        !          1298:                            (caddr_t)ALPHA_PHYS_TO_K0SEG(maddr), n);
        !          1299:                        if (error)
        !          1300:                                goto err;
        !          1301:                        maddr += n;
        !          1302:                        blkno += btodb(n);                      /* XXX? */
        !          1303:
        !          1304:                        /* XXX should look for keystrokes, to cancel. */
        !          1305:                }
        !          1306:        }
        !          1307:
        !          1308: err:
        !          1309:        switch (error) {
        !          1310: #ifdef DEBUG
        !          1311:        case ENXIO:
        !          1312:                printf("device bad\n");
        !          1313:                break;
        !          1314:
        !          1315:        case EFAULT:
        !          1316:                printf("device not ready\n");
        !          1317:                break;
        !          1318:
        !          1319:        case EINVAL:
        !          1320:                printf("area improper\n");
        !          1321:                break;
        !          1322:
        !          1323:        case EIO:
        !          1324:                printf("i/o error\n");
        !          1325:                break;
        !          1326:
        !          1327:        case EINTR:
        !          1328:                printf("aborted from console\n");
        !          1329:                break;
        !          1330: #endif /* DEBUG */
        !          1331:        case 0:
        !          1332:                printf("succeeded\n");
        !          1333:                break;
        !          1334:
        !          1335:        default:
        !          1336:                printf("error %d\n", error);
        !          1337:                break;
        !          1338:        }
        !          1339:        printf("\n\n");
        !          1340:        delay(1000);
        !          1341: }
        !          1342:
        !          1343: void
        !          1344: frametoreg(framep, regp)
        !          1345:        struct trapframe *framep;
        !          1346:        struct reg *regp;
        !          1347: {
        !          1348:
        !          1349:        regp->r_regs[R_V0] = framep->tf_regs[FRAME_V0];
        !          1350:        regp->r_regs[R_T0] = framep->tf_regs[FRAME_T0];
        !          1351:        regp->r_regs[R_T1] = framep->tf_regs[FRAME_T1];
        !          1352:        regp->r_regs[R_T2] = framep->tf_regs[FRAME_T2];
        !          1353:        regp->r_regs[R_T3] = framep->tf_regs[FRAME_T3];
        !          1354:        regp->r_regs[R_T4] = framep->tf_regs[FRAME_T4];
        !          1355:        regp->r_regs[R_T5] = framep->tf_regs[FRAME_T5];
        !          1356:        regp->r_regs[R_T6] = framep->tf_regs[FRAME_T6];
        !          1357:        regp->r_regs[R_T7] = framep->tf_regs[FRAME_T7];
        !          1358:        regp->r_regs[R_S0] = framep->tf_regs[FRAME_S0];
        !          1359:        regp->r_regs[R_S1] = framep->tf_regs[FRAME_S1];
        !          1360:        regp->r_regs[R_S2] = framep->tf_regs[FRAME_S2];
        !          1361:        regp->r_regs[R_S3] = framep->tf_regs[FRAME_S3];
        !          1362:        regp->r_regs[R_S4] = framep->tf_regs[FRAME_S4];
        !          1363:        regp->r_regs[R_S5] = framep->tf_regs[FRAME_S5];
        !          1364:        regp->r_regs[R_S6] = framep->tf_regs[FRAME_S6];
        !          1365:        regp->r_regs[R_A0] = framep->tf_regs[FRAME_A0];
        !          1366:        regp->r_regs[R_A1] = framep->tf_regs[FRAME_A1];
        !          1367:        regp->r_regs[R_A2] = framep->tf_regs[FRAME_A2];
        !          1368:        regp->r_regs[R_A3] = framep->tf_regs[FRAME_A3];
        !          1369:        regp->r_regs[R_A4] = framep->tf_regs[FRAME_A4];
        !          1370:        regp->r_regs[R_A5] = framep->tf_regs[FRAME_A5];
        !          1371:        regp->r_regs[R_T8] = framep->tf_regs[FRAME_T8];
        !          1372:        regp->r_regs[R_T9] = framep->tf_regs[FRAME_T9];
        !          1373:        regp->r_regs[R_T10] = framep->tf_regs[FRAME_T10];
        !          1374:        regp->r_regs[R_T11] = framep->tf_regs[FRAME_T11];
        !          1375:        regp->r_regs[R_RA] = framep->tf_regs[FRAME_RA];
        !          1376:        regp->r_regs[R_T12] = framep->tf_regs[FRAME_T12];
        !          1377:        regp->r_regs[R_AT] = framep->tf_regs[FRAME_AT];
        !          1378:        regp->r_regs[R_GP] = framep->tf_regs[FRAME_GP];
        !          1379:        /* regp->r_regs[R_SP] = framep->tf_regs[FRAME_SP]; XXX */
        !          1380:        regp->r_regs[R_ZERO] = 0;
        !          1381: }
        !          1382:
        !          1383: void
        !          1384: regtoframe(regp, framep)
        !          1385:        struct reg *regp;
        !          1386:        struct trapframe *framep;
        !          1387: {
        !          1388:
        !          1389:        framep->tf_regs[FRAME_V0] = regp->r_regs[R_V0];
        !          1390:        framep->tf_regs[FRAME_T0] = regp->r_regs[R_T0];
        !          1391:        framep->tf_regs[FRAME_T1] = regp->r_regs[R_T1];
        !          1392:        framep->tf_regs[FRAME_T2] = regp->r_regs[R_T2];
        !          1393:        framep->tf_regs[FRAME_T3] = regp->r_regs[R_T3];
        !          1394:        framep->tf_regs[FRAME_T4] = regp->r_regs[R_T4];
        !          1395:        framep->tf_regs[FRAME_T5] = regp->r_regs[R_T5];
        !          1396:        framep->tf_regs[FRAME_T6] = regp->r_regs[R_T6];
        !          1397:        framep->tf_regs[FRAME_T7] = regp->r_regs[R_T7];
        !          1398:        framep->tf_regs[FRAME_S0] = regp->r_regs[R_S0];
        !          1399:        framep->tf_regs[FRAME_S1] = regp->r_regs[R_S1];
        !          1400:        framep->tf_regs[FRAME_S2] = regp->r_regs[R_S2];
        !          1401:        framep->tf_regs[FRAME_S3] = regp->r_regs[R_S3];
        !          1402:        framep->tf_regs[FRAME_S4] = regp->r_regs[R_S4];
        !          1403:        framep->tf_regs[FRAME_S5] = regp->r_regs[R_S5];
        !          1404:        framep->tf_regs[FRAME_S6] = regp->r_regs[R_S6];
        !          1405:        framep->tf_regs[FRAME_A0] = regp->r_regs[R_A0];
        !          1406:        framep->tf_regs[FRAME_A1] = regp->r_regs[R_A1];
        !          1407:        framep->tf_regs[FRAME_A2] = regp->r_regs[R_A2];
        !          1408:        framep->tf_regs[FRAME_A3] = regp->r_regs[R_A3];
        !          1409:        framep->tf_regs[FRAME_A4] = regp->r_regs[R_A4];
        !          1410:        framep->tf_regs[FRAME_A5] = regp->r_regs[R_A5];
        !          1411:        framep->tf_regs[FRAME_T8] = regp->r_regs[R_T8];
        !          1412:        framep->tf_regs[FRAME_T9] = regp->r_regs[R_T9];
        !          1413:        framep->tf_regs[FRAME_T10] = regp->r_regs[R_T10];
        !          1414:        framep->tf_regs[FRAME_T11] = regp->r_regs[R_T11];
        !          1415:        framep->tf_regs[FRAME_RA] = regp->r_regs[R_RA];
        !          1416:        framep->tf_regs[FRAME_T12] = regp->r_regs[R_T12];
        !          1417:        framep->tf_regs[FRAME_AT] = regp->r_regs[R_AT];
        !          1418:        framep->tf_regs[FRAME_GP] = regp->r_regs[R_GP];
        !          1419:        /* framep->tf_regs[FRAME_SP] = regp->r_regs[R_SP]; XXX */
        !          1420:        /* ??? = regp->r_regs[R_ZERO]; */
        !          1421: }
        !          1422:
        !          1423: void
        !          1424: printregs(regp)
        !          1425:        struct reg *regp;
        !          1426: {
        !          1427:        int i;
        !          1428:
        !          1429:        for (i = 0; i < 32; i++)
        !          1430:                printf("R%d:\t0x%016lx%s", i, regp->r_regs[i],
        !          1431:                   i & 1 ? "\n" : "\t");
        !          1432: }
        !          1433:
        !          1434: void
        !          1435: regdump(framep)
        !          1436:        struct trapframe *framep;
        !          1437: {
        !          1438:        struct reg reg;
        !          1439:
        !          1440:        frametoreg(framep, &reg);
        !          1441:        reg.r_regs[R_SP] = alpha_pal_rdusp();
        !          1442:
        !          1443:        printf("REGISTERS:\n");
        !          1444:        printregs(&reg);
        !          1445: }
        !          1446:
        !          1447: #ifdef DEBUG
        !          1448: int sigdebug = 0;
        !          1449: int sigpid = 0;
        !          1450: #define        SDB_FOLLOW      0x01
        !          1451: #define        SDB_KSTACK      0x02
        !          1452: #endif
        !          1453:
        !          1454: /*
        !          1455:  * Send an interrupt to process.
        !          1456:  */
        !          1457: void
        !          1458: sendsig(catcher, sig, mask, code, type, val)
        !          1459:        sig_t catcher;
        !          1460:        int sig, mask;
        !          1461:        u_long code;
        !          1462:        int type;
        !          1463:        union sigval val;
        !          1464: {
        !          1465:        struct proc *p = curproc;
        !          1466:        struct sigcontext *scp, ksc;
        !          1467:        struct trapframe *frame;
        !          1468:        struct sigacts *psp = p->p_sigacts;
        !          1469:        int oonstack, fsize, rndfsize, kscsize;
        !          1470:        siginfo_t *sip, ksi;
        !          1471:
        !          1472:        frame = p->p_md.md_tf;
        !          1473:        oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
        !          1474:        fsize = sizeof ksc;
        !          1475:        rndfsize = ((fsize + 15) / 16) * 16;
        !          1476:        kscsize = rndfsize;
        !          1477:        if (psp->ps_siginfo & sigmask(sig)) {
        !          1478:                fsize += sizeof ksi;
        !          1479:                rndfsize = ((fsize + 15) / 16) * 16;
        !          1480:        }
        !          1481:
        !          1482:        /*
        !          1483:         * Allocate and validate space for the signal handler
        !          1484:         * context. Note that if the stack is in P0 space, the
        !          1485:         * call to uvm_grow() is a nop, and the useracc() check
        !          1486:         * will fail if the process has not already allocated
        !          1487:         * the space with a `brk'.
        !          1488:         */
        !          1489:        if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
        !          1490:            (psp->ps_sigonstack & sigmask(sig))) {
        !          1491:                scp = (struct sigcontext *)(psp->ps_sigstk.ss_sp +
        !          1492:                    psp->ps_sigstk.ss_size - rndfsize);
        !          1493:                psp->ps_sigstk.ss_flags |= SS_ONSTACK;
        !          1494:        } else
        !          1495:                scp = (struct sigcontext *)(alpha_pal_rdusp() - rndfsize);
        !          1496:        if ((u_long)scp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
        !          1497:                (void)uvm_grow(p, (u_long)scp);
        !          1498: #ifdef DEBUG
        !          1499:        if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
        !          1500:                printf("sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid,
        !          1501:                    sig, &oonstack, scp);
        !          1502: #endif
        !          1503:
        !          1504:        /*
        !          1505:         * Build the signal context to be used by sigreturn.
        !          1506:         */
        !          1507:        ksc.sc_onstack = oonstack;
        !          1508:        ksc.sc_mask = mask;
        !          1509:        ksc.sc_pc = frame->tf_regs[FRAME_PC];
        !          1510:        ksc.sc_ps = frame->tf_regs[FRAME_PS];
        !          1511:
        !          1512:        /* copy the registers. */
        !          1513:        frametoreg(frame, (struct reg *)ksc.sc_regs);
        !          1514:        ksc.sc_regs[R_ZERO] = 0xACEDBADE;               /* magic number */
        !          1515:        ksc.sc_regs[R_SP] = alpha_pal_rdusp();
        !          1516:
        !          1517:        /* save the floating-point state, if necessary, then copy it. */
        !          1518:        if (p->p_addr->u_pcb.pcb_fpcpu != NULL)
        !          1519:                fpusave_proc(p, 1);
        !          1520:        ksc.sc_ownedfp = p->p_md.md_flags & MDP_FPUSED;
        !          1521:        memcpy((struct fpreg *)ksc.sc_fpregs, &p->p_addr->u_pcb.pcb_fp,
        !          1522:            sizeof(struct fpreg));
        !          1523: #ifndef NO_IEEE
        !          1524:        ksc.sc_fp_control = alpha_read_fp_c(p);
        !          1525: #else
        !          1526:        ksc.sc_fp_control = 0;
        !          1527: #endif
        !          1528:        memset(ksc.sc_reserved, 0, sizeof ksc.sc_reserved);     /* XXX */
        !          1529:        memset(ksc.sc_xxx, 0, sizeof ksc.sc_xxx);               /* XXX */
        !          1530:
        !          1531: #ifdef COMPAT_OSF1
        !          1532:        /*
        !          1533:         * XXX Create an OSF/1-style sigcontext and associated goo.
        !          1534:         */
        !          1535: #endif
        !          1536:
        !          1537:        if (psp->ps_siginfo & sigmask(sig)) {
        !          1538:                initsiginfo(&ksi, sig, code, type, val);
        !          1539:                sip = (void *)scp + kscsize;
        !          1540:                if (copyout((caddr_t)&ksi, (caddr_t)sip, fsize - kscsize) != 0)
        !          1541:                        goto trash;
        !          1542:        } else
        !          1543:                sip = NULL;
        !          1544:
        !          1545:        /*
        !          1546:         * copy the frame out to userland.
        !          1547:         */
        !          1548:        if (copyout((caddr_t)&ksc, (caddr_t)scp, kscsize) != 0) {
        !          1549: trash:
        !          1550: #ifdef DEBUG
        !          1551:                if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
        !          1552:                        printf("sendsig(%d): copyout failed on sig %d\n",
        !          1553:                            p->p_pid, sig);
        !          1554: #endif
        !          1555:                /*
        !          1556:                 * Process has trashed its stack; give it an illegal
        !          1557:                 * instruction to halt it in its tracks.
        !          1558:                 */
        !          1559:                sigexit(p, SIGILL);
        !          1560:                /* NOTREACHED */
        !          1561:        }
        !          1562: #ifdef DEBUG
        !          1563:        if (sigdebug & SDB_FOLLOW)
        !          1564:                printf("sendsig(%d): sig %d scp %p code %lx\n", p->p_pid, sig,
        !          1565:                    scp, code);
        !          1566: #endif
        !          1567:
        !          1568:        /*
        !          1569:         * Set up the registers to return to sigcode.
        !          1570:         */
        !          1571:        frame->tf_regs[FRAME_PC] = p->p_sigcode;
        !          1572:        frame->tf_regs[FRAME_A0] = sig;
        !          1573:        frame->tf_regs[FRAME_A1] = (u_int64_t)sip;
        !          1574:        frame->tf_regs[FRAME_A2] = (u_int64_t)scp;
        !          1575:        frame->tf_regs[FRAME_T12] = (u_int64_t)catcher;         /* t12 is pv */
        !          1576:        alpha_pal_wrusp((unsigned long)scp);
        !          1577:
        !          1578: #ifdef DEBUG
        !          1579:        if (sigdebug & SDB_FOLLOW)
        !          1580:                printf("sendsig(%d): pc %lx, catcher %lx\n", p->p_pid,
        !          1581:                    frame->tf_regs[FRAME_PC], frame->tf_regs[FRAME_A3]);
        !          1582:        if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
        !          1583:                printf("sendsig(%d): sig %d returns\n",
        !          1584:                    p->p_pid, sig);
        !          1585: #endif
        !          1586: }
        !          1587:
        !          1588: /*
        !          1589:  * System call to cleanup state after a signal
        !          1590:  * has been taken.  Reset signal mask and
        !          1591:  * stack state from context left by sendsig (above).
        !          1592:  * Return to previous pc and psl as specified by
        !          1593:  * context left by sendsig. Check carefully to
        !          1594:  * make sure that the user has not modified the
        !          1595:  * psl to gain improper privileges or to cause
        !          1596:  * a machine fault.
        !          1597:  */
        !          1598: /* ARGSUSED */
        !          1599: int
        !          1600: sys_sigreturn(p, v, retval)
        !          1601:        struct proc *p;
        !          1602:        void *v;
        !          1603:        register_t *retval;
        !          1604: {
        !          1605:        struct sys_sigreturn_args /* {
        !          1606:                syscallarg(struct sigcontext *) sigcntxp;
        !          1607:        } */ *uap = v;
        !          1608:        struct sigcontext ksc;
        !          1609: #ifdef DEBUG
        !          1610:        struct sigcontext *scp;
        !          1611: #endif
        !          1612:        int error;
        !          1613:
        !          1614: #ifdef DEBUG
        !          1615:        if (sigdebug & SDB_FOLLOW)
        !          1616:            printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
        !          1617: #endif
        !          1618:
        !          1619:        /*
        !          1620:         * Test and fetch the context structure.
        !          1621:         * We grab it all at once for speed.
        !          1622:         */
        !          1623:        if ((error = copyin(SCARG(uap, sigcntxp), &ksc, sizeof(ksc))) != 0)
        !          1624:                return (error);
        !          1625:
        !          1626:        if (ksc.sc_regs[R_ZERO] != 0xACEDBADE)          /* magic number */
        !          1627:                return (EINVAL);
        !          1628:        /*
        !          1629:         * Restore the user-supplied information
        !          1630:         */
        !          1631:        if (ksc.sc_onstack)
        !          1632:                p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
        !          1633:        else
        !          1634:                p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
        !          1635:        p->p_sigmask = ksc.sc_mask &~ sigcantmask;
        !          1636:
        !          1637:        p->p_md.md_tf->tf_regs[FRAME_PC] = ksc.sc_pc;
        !          1638:        p->p_md.md_tf->tf_regs[FRAME_PS] =
        !          1639:            (ksc.sc_ps | ALPHA_PSL_USERSET) & ~ALPHA_PSL_USERCLR;
        !          1640:
        !          1641:        regtoframe((struct reg *)ksc.sc_regs, p->p_md.md_tf);
        !          1642:        alpha_pal_wrusp(ksc.sc_regs[R_SP]);
        !          1643:
        !          1644:        /* XXX ksc.sc_ownedfp ? */
        !          1645:        if (p->p_addr->u_pcb.pcb_fpcpu != NULL)
        !          1646:                fpusave_proc(p, 0);
        !          1647:        memcpy(&p->p_addr->u_pcb.pcb_fp, (struct fpreg *)ksc.sc_fpregs,
        !          1648:            sizeof(struct fpreg));
        !          1649: #ifndef NO_IEEE
        !          1650:        p->p_addr->u_pcb.pcb_fp.fpr_cr = ksc.sc_fpcr;
        !          1651:        p->p_md.md_flags = ksc.sc_fp_control & MDP_FP_C;
        !          1652: #endif
        !          1653:
        !          1654: #ifdef DEBUG
        !          1655:        if (sigdebug & SDB_FOLLOW)
        !          1656:                printf("sigreturn(%d): returns\n", p->p_pid);
        !          1657: #endif
        !          1658:        return (EJUSTRETURN);
        !          1659: }
        !          1660:
        !          1661: /*
        !          1662:  * machine dependent system variables.
        !          1663:  */
        !          1664: int
        !          1665: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
        !          1666:        int *name;
        !          1667:        u_int namelen;
        !          1668:        void *oldp;
        !          1669:        size_t *oldlenp;
        !          1670:        void *newp;
        !          1671:        size_t newlen;
        !          1672:        struct proc *p;
        !          1673: {
        !          1674:        dev_t consdev;
        !          1675:
        !          1676:        if (name[0] != CPU_CHIPSET && namelen != 1)
        !          1677:                return (ENOTDIR);               /* overloaded */
        !          1678:
        !          1679:        switch (name[0]) {
        !          1680:        case CPU_CONSDEV:
        !          1681:                if (cn_tab != NULL)
        !          1682:                        consdev = cn_tab->cn_dev;
        !          1683:                else
        !          1684:                        consdev = NODEV;
        !          1685:                return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
        !          1686:                        sizeof consdev));
        !          1687:
        !          1688:        case CPU_ROOT_DEVICE:
        !          1689:                return (sysctl_rdstring(oldp, oldlenp, newp,
        !          1690:                    root_device));
        !          1691: #ifndef SMALL_KERNEL
        !          1692:        case CPU_UNALIGNED_PRINT:
        !          1693:                return (sysctl_int(oldp, oldlenp, newp, newlen,
        !          1694:                    &alpha_unaligned_print));
        !          1695:
        !          1696:        case CPU_UNALIGNED_FIX:
        !          1697:                return (sysctl_int(oldp, oldlenp, newp, newlen,
        !          1698:                    &alpha_unaligned_fix));
        !          1699:
        !          1700:        case CPU_UNALIGNED_SIGBUS:
        !          1701:                return (sysctl_int(oldp, oldlenp, newp, newlen,
        !          1702:                    &alpha_unaligned_sigbus));
        !          1703:
        !          1704:        case CPU_BOOTED_KERNEL:
        !          1705:                return (sysctl_rdstring(oldp, oldlenp, newp,
        !          1706:                    bootinfo.booted_kernel));
        !          1707:
        !          1708:        case CPU_CHIPSET:
        !          1709:                return (alpha_sysctl_chipset(name + 1, namelen - 1, oldp,
        !          1710:                    oldlenp));
        !          1711: #endif /* SMALL_KERNEL */
        !          1712:
        !          1713: #ifndef NO_IEEE
        !          1714:        case CPU_FP_SYNC_COMPLETE:
        !          1715:                return (sysctl_int(oldp, oldlenp, newp, newlen,
        !          1716:                    &alpha_fp_sync_complete));
        !          1717: #endif
        !          1718:        case CPU_ALLOWAPERTURE:
        !          1719: #ifdef APERTURE
        !          1720:                if (securelevel > 0)
        !          1721:                        return (sysctl_int_lower(oldp, oldlenp, newp, newlen,
        !          1722:                            &allowaperture));
        !          1723:                 else
        !          1724:                         return (sysctl_int(oldp, oldlenp, newp, newlen,
        !          1725:                             &allowaperture));
        !          1726: #else
        !          1727:                return (sysctl_rdint(oldp, oldlenp, newp, 0));
        !          1728: #endif
        !          1729:        default:
        !          1730:                return (EOPNOTSUPP);
        !          1731:        }
        !          1732:        /* NOTREACHED */
        !          1733: }
        !          1734:
        !          1735: /*
        !          1736:  * Set registers on exec.
        !          1737:  */
        !          1738: void
        !          1739: setregs(p, pack, stack, retval)
        !          1740:        register struct proc *p;
        !          1741:        struct exec_package *pack;
        !          1742:        u_long stack;
        !          1743:        register_t *retval;
        !          1744: {
        !          1745:        struct trapframe *tfp = p->p_md.md_tf;
        !          1746: #ifdef DEBUG
        !          1747:        int i;
        !          1748: #endif
        !          1749:
        !          1750: #ifdef DEBUG
        !          1751:        /*
        !          1752:         * Crash and dump, if the user requested it.
        !          1753:         */
        !          1754:        if (boothowto & RB_DUMP)
        !          1755:                panic("crash requested by boot flags");
        !          1756: #endif
        !          1757:
        !          1758: #ifdef DEBUG
        !          1759:        for (i = 0; i < FRAME_SIZE; i++)
        !          1760:                tfp->tf_regs[i] = 0xbabefacedeadbeef;
        !          1761: #else
        !          1762:        bzero(tfp->tf_regs, FRAME_SIZE * sizeof tfp->tf_regs[0]);
        !          1763: #endif
        !          1764:        bzero(&p->p_addr->u_pcb.pcb_fp, sizeof p->p_addr->u_pcb.pcb_fp);
        !          1765:        alpha_pal_wrusp(stack);
        !          1766:        tfp->tf_regs[FRAME_PS] = ALPHA_PSL_USERSET;
        !          1767:        tfp->tf_regs[FRAME_PC] = pack->ep_entry & ~3;
        !          1768:
        !          1769:        tfp->tf_regs[FRAME_A0] = stack;
        !          1770:        /* a1 and a2 already zeroed */
        !          1771:        tfp->tf_regs[FRAME_T12] = tfp->tf_regs[FRAME_PC];       /* a.k.a. PV */
        !          1772:
        !          1773:        p->p_md.md_flags &= ~MDP_FPUSED;
        !          1774: #ifndef NO_IEEE
        !          1775:        if (__predict_true((p->p_md.md_flags & IEEE_INHERIT) == 0)) {
        !          1776:                p->p_md.md_flags &= ~MDP_FP_C;
        !          1777:                p->p_addr->u_pcb.pcb_fp.fpr_cr = FPCR_DYN(FP_RN);
        !          1778:        }
        !          1779: #endif
        !          1780:        if (p->p_addr->u_pcb.pcb_fpcpu != NULL)
        !          1781:                fpusave_proc(p, 0);
        !          1782:
        !          1783:        retval[1] = 0;
        !          1784: }
        !          1785:
        !          1786: /*
        !          1787:  * Release the FPU.
        !          1788:  */
        !          1789: void
        !          1790: fpusave_cpu(struct cpu_info *ci, int save)
        !          1791: {
        !          1792:        struct proc *p;
        !          1793:
        !          1794:        KDASSERT(ci == curcpu());
        !          1795:
        !          1796: #if defined(MULTIPROCESSOR)
        !          1797:        atomic_setbits_ulong(&ci->ci_flags, CPUF_FPUSAVE);
        !          1798: #endif
        !          1799:
        !          1800:        p = ci->ci_fpcurproc;
        !          1801:        if (p == NULL)
        !          1802:                goto out;
        !          1803:
        !          1804:        if (save) {
        !          1805:                alpha_pal_wrfen(1);
        !          1806:                savefpstate(&p->p_addr->u_pcb.pcb_fp);
        !          1807:        }
        !          1808:
        !          1809:        alpha_pal_wrfen(0);
        !          1810:
        !          1811:        p->p_addr->u_pcb.pcb_fpcpu = NULL;
        !          1812:        ci->ci_fpcurproc = NULL;
        !          1813:
        !          1814: out:
        !          1815: #if defined(MULTIPROCESSOR)
        !          1816:        atomic_clearbits_ulong(&ci->ci_flags, CPUF_FPUSAVE);
        !          1817: #endif
        !          1818:        return;
        !          1819: }
        !          1820:
        !          1821: /*
        !          1822:  * Synchronize FP state for this process.
        !          1823:  */
        !          1824: void
        !          1825: fpusave_proc(struct proc *p, int save)
        !          1826: {
        !          1827:        struct cpu_info *ci = curcpu();
        !          1828:        struct cpu_info *oci;
        !          1829: #if defined(MULTIPROCESSOR)
        !          1830:        u_long ipi = save ? ALPHA_IPI_SYNCH_FPU : ALPHA_IPI_DISCARD_FPU;
        !          1831:        int spincount;
        !          1832: #endif
        !          1833:
        !          1834:        KDASSERT(p->p_addr != NULL);
        !          1835:
        !          1836:        oci = p->p_addr->u_pcb.pcb_fpcpu;
        !          1837:        if (oci == NULL) {
        !          1838:                return;
        !          1839:        }
        !          1840:
        !          1841: #if defined(MULTIPROCESSOR)
        !          1842:        if (oci == ci) {
        !          1843:                KASSERT(ci->ci_fpcurproc == p);
        !          1844:                fpusave_cpu(ci, save);
        !          1845:                return;
        !          1846:        }
        !          1847:
        !          1848:        KASSERT(oci->ci_fpcurproc == p);
        !          1849:        alpha_send_ipi(oci->ci_cpuid, ipi);
        !          1850:
        !          1851:        spincount = 0;
        !          1852:        while (p->p_addr->u_pcb.pcb_fpcpu != NULL) {
        !          1853:                spincount++;
        !          1854:                delay(1000);    /* XXX */
        !          1855:                if (spincount > 10000)
        !          1856:                        panic("fpsave ipi didn't");
        !          1857:        }
        !          1858: #else
        !          1859:        KASSERT(ci->ci_fpcurproc == p);
        !          1860:        fpusave_cpu(ci, save);
        !          1861: #endif /* MULTIPROCESSOR */
        !          1862: }
        !          1863:
        !          1864: int
        !          1865: spl0()
        !          1866: {
        !          1867:
        !          1868:        if (ssir) {
        !          1869:                (void) alpha_pal_swpipl(ALPHA_PSL_IPL_SOFT);
        !          1870:                softintr_dispatch();
        !          1871:        }
        !          1872:
        !          1873:        return (alpha_pal_swpipl(ALPHA_PSL_IPL_0));
        !          1874: }
        !          1875:
        !          1876: /*
        !          1877:  * The following primitives manipulate the run queues.  _whichqs tells which
        !          1878:  * of the 32 queues _qs have processes in them.  Setrunqueue puts processes
        !          1879:  * into queues, Remrunqueue removes them from queues.  The running process is
        !          1880:  * on no queue, other processes are on a queue related to p->p_priority,
        !          1881:  * divided by 4 actually to shrink the 0-127 range of priorities into the 32
        !          1882:  * available queues.
        !          1883:  */
        !          1884: /*
        !          1885:  * setrunqueue(p)
        !          1886:  *     proc *p;
        !          1887:  *
        !          1888:  * Call should be made at splclock(), and p->p_stat should be SRUN.
        !          1889:  */
        !          1890:
        !          1891: /* XXXART - grmble */
        !          1892: #define sched_qs qs
        !          1893: #define sched_whichqs whichqs
        !          1894:
        !          1895: void
        !          1896: setrunqueue(p)
        !          1897:        struct proc *p;
        !          1898: {
        !          1899:        int bit;
        !          1900:
        !          1901:        /* firewall: p->p_back must be NULL */
        !          1902:        if (p->p_back != NULL)
        !          1903:                panic("setrunqueue");
        !          1904:
        !          1905:        bit = p->p_priority >> 2;
        !          1906:        sched_whichqs |= (1 << bit);
        !          1907:        p->p_forw = (struct proc *)&sched_qs[bit];
        !          1908:        p->p_back = sched_qs[bit].ph_rlink;
        !          1909:        p->p_back->p_forw = p;
        !          1910:        sched_qs[bit].ph_rlink = p;
        !          1911: }
        !          1912:
        !          1913: /*
        !          1914:  * remrunqueue(p)
        !          1915:  *
        !          1916:  * Call should be made at splclock().
        !          1917:  */
        !          1918: void
        !          1919: remrunqueue(p)
        !          1920:        struct proc *p;
        !          1921: {
        !          1922:        int bit;
        !          1923:
        !          1924:        bit = p->p_priority >> 2;
        !          1925:        if ((sched_whichqs & (1 << bit)) == 0)
        !          1926:                panic("remrunqueue");
        !          1927:
        !          1928:        p->p_back->p_forw = p->p_forw;
        !          1929:        p->p_forw->p_back = p->p_back;
        !          1930:        p->p_back = NULL;       /* for firewall checking. */
        !          1931:
        !          1932:        if ((struct proc *)&sched_qs[bit] == sched_qs[bit].ph_link)
        !          1933:                sched_whichqs &= ~(1 << bit);
        !          1934: }
        !          1935:
        !          1936: /*
        !          1937:  * Wait "n" microseconds.
        !          1938:  */
        !          1939: void
        !          1940: delay(n)
        !          1941:        unsigned long n;
        !          1942: {
        !          1943:        unsigned long pcc0, pcc1, curcycle, cycles, usec;
        !          1944:
        !          1945:        if (n == 0)
        !          1946:                return;
        !          1947:
        !          1948:        pcc0 = alpha_rpcc() & 0xffffffffUL;
        !          1949:        cycles = 0;
        !          1950:        usec = 0;
        !          1951:
        !          1952:        while (usec <= n) {
        !          1953:                /*
        !          1954:                 * Get the next CPU cycle count - assumes that we can not
        !          1955:                 * have had more than one 32 bit overflow.
        !          1956:                 */
        !          1957:                pcc1 = alpha_rpcc() & 0xffffffffUL;
        !          1958:                if (pcc1 < pcc0)
        !          1959:                        curcycle = (pcc1 + 0x100000000UL) - pcc0;
        !          1960:                else
        !          1961:                        curcycle = pcc1 - pcc0;
        !          1962:
        !          1963:                /*
        !          1964:                 * We now have the number of processor cycles since we
        !          1965:                 * last checked. Add the current cycle count to the
        !          1966:                 * running total. If it's over cycles_per_usec, increment
        !          1967:                 * the usec counter.
        !          1968:                 */
        !          1969:                cycles += curcycle;
        !          1970:                while (cycles > cycles_per_usec) {
        !          1971:                        usec++;
        !          1972:                        cycles -= cycles_per_usec;
        !          1973:                }
        !          1974:                pcc0 = pcc1;
        !          1975:        }
        !          1976: }
        !          1977:
        !          1978: #if defined(COMPAT_OSF1)
        !          1979: void   cpu_exec_ecoff_setregs(struct proc *, struct exec_package *,
        !          1980:            u_long, register_t *);
        !          1981:
        !          1982: void
        !          1983: cpu_exec_ecoff_setregs(p, epp, stack, retval)
        !          1984:        struct proc *p;
        !          1985:        struct exec_package *epp;
        !          1986:        u_long stack;
        !          1987:        register_t *retval;
        !          1988: {
        !          1989:        struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr;
        !          1990:
        !          1991:        setregs(p, epp, stack, retval);
        !          1992:        p->p_md.md_tf->tf_regs[FRAME_GP] = execp->a.gp_value;
        !          1993: }
        !          1994:
        !          1995: /*
        !          1996:  * cpu_exec_ecoff_hook():
        !          1997:  *     cpu-dependent ECOFF format hook for execve().
        !          1998:  *
        !          1999:  * Do any machine-dependent diddling of the exec package when doing ECOFF.
        !          2000:  *
        !          2001:  */
        !          2002: int
        !          2003: cpu_exec_ecoff_hook(p, epp)
        !          2004:        struct proc *p;
        !          2005:        struct exec_package *epp;
        !          2006: {
        !          2007:        struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr;
        !          2008:        extern struct emul emul_native;
        !          2009:        int error;
        !          2010:        extern int osf1_exec_ecoff_hook(struct proc *, struct exec_package *);
        !          2011:
        !          2012:        switch (execp->f.f_magic) {
        !          2013: #ifdef COMPAT_OSF1
        !          2014:        case ECOFF_MAGIC_ALPHA:
        !          2015:                error = osf1_exec_ecoff_hook(p, epp);
        !          2016:                break;
        !          2017: #endif
        !          2018:
        !          2019:        case ECOFF_MAGIC_NATIVE_ALPHA:
        !          2020:                epp->ep_emul = &emul_native;
        !          2021:                error = 0;
        !          2022:                break;
        !          2023:
        !          2024:        default:
        !          2025:                error = ENOEXEC;
        !          2026:        }
        !          2027:        return (error);
        !          2028: }
        !          2029: #endif
        !          2030:
        !          2031: int
        !          2032: alpha_pa_access(pa)
        !          2033:        u_long pa;
        !          2034: {
        !          2035:        int i;
        !          2036:
        !          2037:        for (i = 0; i < mem_cluster_cnt; i++) {
        !          2038:                if (pa < mem_clusters[i].start)
        !          2039:                        continue;
        !          2040:                if ((pa - mem_clusters[i].start) >=
        !          2041:                    (mem_clusters[i].size & ~PAGE_MASK))
        !          2042:                        continue;
        !          2043:                return (mem_clusters[i].size & PAGE_MASK);      /* prot */
        !          2044:        }
        !          2045:
        !          2046:        /*
        !          2047:         * Address is not a memory address.  If we're secure, disallow
        !          2048:         * access.  Otherwise, grant read/write.
        !          2049:         */
        !          2050:        if (securelevel > 0)
        !          2051:                return (VM_PROT_NONE);
        !          2052:        else
        !          2053:                return (VM_PROT_READ | VM_PROT_WRITE);
        !          2054: }
        !          2055:
        !          2056: /* XXX XXX BEGIN XXX XXX */
        !          2057: paddr_t alpha_XXX_dmamap_or;                                   /* XXX */
        !          2058:                                                                /* XXX */
        !          2059: paddr_t                                                                /* XXX */
        !          2060: alpha_XXX_dmamap(v)                                            /* XXX */
        !          2061:        vaddr_t v;                                              /* XXX */
        !          2062: {                                                              /* XXX */
        !          2063:                                                                /* XXX */
        !          2064:        return (vtophys(v) | alpha_XXX_dmamap_or);              /* XXX */
        !          2065: }                                                              /* XXX */
        !          2066: /* XXX XXX END XXX XXX */

CVSweb