[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

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