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

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

1.1       nbrk        1: /*     $OpenBSD: machdep.c,v 1.113 2007/06/06 17:15:12 deraadt Exp $   */
                      2: /*     $NetBSD: machdep.c,v 1.85 1997/09/12 08:55:02 pk Exp $ */
                      3:
                      4: /*
                      5:  * Copyright (c) 1992, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  *
                      8:  * This software was developed by the Computer Systems Engineering group
                      9:  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
                     10:  * contributed to Berkeley.
                     11:  *
                     12:  * All advertising materials mentioning features or use of this software
                     13:  * must display the following acknowledgement:
                     14:  *     This product includes software developed by the University of
                     15:  *     California, Lawrence Berkeley Laboratory.
                     16:  *
                     17:  * Redistribution and use in source and binary forms, with or without
                     18:  * modification, are permitted provided that the following conditions
                     19:  * are met:
                     20:  * 1. Redistributions of source code must retain the above copyright
                     21:  *    notice, this list of conditions and the following disclaimer.
                     22:  * 2. Redistributions in binary form must reproduce the above copyright
                     23:  *    notice, this list of conditions and the following disclaimer in the
                     24:  *    documentation and/or other materials provided with the distribution.
                     25:  * 3. Neither the name of the University nor the names of its contributors
                     26:  *    may be used to endorse or promote products derived from this software
                     27:  *    without specific prior written permission.
                     28:  *
                     29:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     30:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     31:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     32:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     33:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     34:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     35:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     36:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     37:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     38:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     39:  * SUCH DAMAGE.
                     40:  *
                     41:  *     @(#)machdep.c   8.6 (Berkeley) 1/14/94
                     42:  */
                     43:
                     44: #include <sys/param.h>
                     45: #include <sys/signal.h>
                     46: #include <sys/signalvar.h>
                     47: #include <sys/proc.h>
                     48: #include <sys/user.h>
                     49: #include <sys/buf.h>
                     50: #include <sys/device.h>
                     51: #include <sys/reboot.h>
                     52: #include <sys/systm.h>
                     53: #include <sys/conf.h>
                     54: #include <sys/file.h>
                     55: #include <sys/timeout.h>
                     56: #include <sys/malloc.h>
                     57: #include <sys/mbuf.h>
                     58: #include <sys/mount.h>
                     59: #include <sys/msgbuf.h>
                     60: #include <sys/syscallargs.h>
                     61: #ifdef SYSVMSG
                     62: #include <sys/msg.h>
                     63: #endif
                     64: #include <sys/exec.h>
                     65: #include <sys/sysctl.h>
                     66: #include <sys/extent.h>
                     67:
                     68: #include <uvm/uvm_extern.h>
                     69:
                     70: #include <dev/rndvar.h>
                     71:
                     72: #include <machine/autoconf.h>
                     73: #include <machine/frame.h>
                     74: #include <machine/cpu.h>
                     75: #include <machine/pmap.h>
                     76: #include <machine/vmparam.h>
                     77: #include <machine/oldmon.h>
                     78: #include <machine/bsd_openprom.h>
                     79:
                     80: #include <sparc/sparc/asm.h>
                     81: #include <sparc/sparc/cache.h>
                     82: #include <sparc/sparc/vaddrs.h>
                     83: #include <sparc/sparc/cpuvar.h>
                     84:
                     85: #include <uvm/uvm.h>
                     86:
                     87: #ifdef SUN4M
                     88: #include "power.h"
                     89: #if NPOWER > 0
                     90: #include <sparc/dev/power.h>
                     91: #endif
                     92: #include "scf.h"
                     93: #include "tctrl.h"
                     94: #if NTCTRL > 0
                     95: #include <sparc/dev/tctrlvar.h>
                     96: #endif
                     97: #endif
                     98:
                     99: #include "auxreg.h"
                    100:
                    101: #ifdef SUN4
                    102: #include <sparc/dev/led.h>
                    103: #include "led.h"
                    104: #endif
                    105:
                    106: struct vm_map *exec_map = NULL;
                    107: struct vm_map *phys_map = NULL;
                    108:
                    109: /*
                    110:  * Declare these as initialized data so we can patch them.
                    111:  */
                    112: #ifndef BUFCACHEPERCENT
                    113: #define BUFCACHEPERCENT 5
                    114: #endif
                    115:
                    116: #ifdef BUFPAGES
                    117: int    bufpages = BUFPAGES;
                    118: #else
                    119: int    bufpages = 0;
                    120: #endif
                    121: int    bufcachepercent = BUFCACHEPERCENT;
                    122:
                    123: int    physmem;
                    124:
                    125: /* sysctl settable */
                    126: int    sparc_led_blink = 0;
                    127:
                    128: /*
                    129:  * safepri is a safe priority for sleep to set for a spin-wait
                    130:  * during autoconfiguration or after a panic.
                    131:  */
                    132: int   safepri = 0;
                    133:
                    134: /*
                    135:  * dvmamap is used to manage DVMA memory. Note: this coincides with
                    136:  * the memory range in `phys_map' (which is mostly a place-holder).
                    137:  */
                    138: vaddr_t dvma_base, dvma_end;
                    139: struct extent *dvmamap_extent;
                    140:
                    141: caddr_t allocsys(caddr_t);
                    142: void   dumpsys(void);
                    143: void   stackdump(void);
                    144:
                    145: /*
                    146:  * Machine-dependent startup code
                    147:  */
                    148: void
                    149: cpu_startup()
                    150: {
                    151:        caddr_t v;
                    152:        int sz;
                    153: #ifdef DEBUG
                    154:        extern int pmapdebug;
                    155:        int opmapdebug = pmapdebug;
                    156: #endif
                    157:        vaddr_t minaddr, maxaddr;
                    158:        extern struct user *proc0paddr;
                    159:
                    160: #ifdef DEBUG
                    161:        pmapdebug = 0;
                    162: #endif
                    163:
                    164:        if (CPU_ISSUN4M) {
                    165:                extern int stackgap_random;
                    166:
                    167:                stackgap_random = STACKGAP_RANDOM_SUN4M;
                    168:        }
                    169:
                    170:        /*
                    171:         * fix message buffer mapping, note phys addr of msgbuf is 0
                    172:         */
                    173:        pmap_map(MSGBUF_VA, 0, MSGBUFSIZE, VM_PROT_READ|VM_PROT_WRITE);
                    174:        initmsgbuf((caddr_t)(MSGBUF_VA + (CPU_ISSUN4 ? 4096 : 0)), MSGBUFSIZE);
                    175:
                    176:        proc0.p_addr = proc0paddr;
                    177:
                    178:        /*
                    179:         * Good {morning,afternoon,evening,night}.
                    180:         */
                    181:        printf(version);
                    182:        /*identifycpu();*/
                    183:        printf("real mem = %u (%uMB)\n", ctob(physmem),
                    184:            ctob(physmem)/1024/1024);
                    185:
                    186:        /*
                    187:         * Find out how much space we need, allocate it,
                    188:         * and then give everything true virtual addresses.
                    189:         */
                    190:        sz = (int)allocsys((caddr_t)0);
                    191:
                    192:        if ((v = (caddr_t)uvm_km_alloc(kernel_map, round_page(sz))) == 0)
                    193:                panic("startup: no room for tables");
                    194:
                    195:        if (allocsys(v) - v != sz)
                    196:                panic("startup: table size inconsistency");
                    197:
                    198:        /*
                    199:         * Determine how many buffers to allocate.
                    200:         * We allocate bufcachepercent% of memory for buffer space.
                    201:         */
                    202:        if (bufpages == 0)
                    203:                bufpages = physmem * bufcachepercent / 100;
                    204:
                    205:        /* Restrict to at most 25% filled kvm */
                    206:        if (bufpages >
                    207:            (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
                    208:                bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
                    209:                    PAGE_SIZE / 4;
                    210:
                    211:        /*
                    212:         * Allocate a submap for exec arguments.  This map effectively
                    213:         * limits the number of processes exec'ing at any time.
                    214:         */
                    215:        minaddr = vm_map_min(kernel_map);
                    216:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
                    217:                                 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
                    218:
                    219:        /*
                    220:         * Allocate a map for physio.  Others use a submap of the kernel
                    221:         * map, but we want one completely separate, even though it uses
                    222:         * the same pmap.
                    223:         */
                    224:        dvma_base = CPU_ISSUN4M ? DVMA4M_BASE : DVMA_BASE;
                    225:        dvma_end = CPU_ISSUN4M ? DVMA4M_END : DVMA_END;
                    226: #if defined(SUN4M)
                    227:        if (CPU_ISSUN4M) {
                    228:                /*
                    229:                 * The DVMA space we want partially overrides kernel_map.
                    230:                 * Allocate it in kernel_map as well to prevent it from being
                    231:                 * used for other things.
                    232:                 */
                    233:                if (uvm_map(kernel_map, &dvma_base,
                    234:                    vm_map_max(kernel_map) - dvma_base,
                    235:                     NULL, UVM_UNKNOWN_OFFSET, 0,
                    236:                     UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE,
                    237:                                 UVM_ADV_NORMAL, 0)))
                    238:                        panic("startup: can not steal dvma map");
                    239:        }
                    240: #endif
                    241:        phys_map = uvm_map_create(pmap_kernel(), dvma_base, dvma_end,
                    242:            VM_MAP_INTRSAFE);
                    243:        if (phys_map == NULL)
                    244:                panic("unable to create DVMA map");
                    245:
                    246:        /*
                    247:         * Allocate DVMA space and dump into a privately managed
                    248:         * resource map for double mappings which is usable from
                    249:         * interrupt contexts.
                    250:         */
                    251:        if (uvm_km_valloc_wait(phys_map, (dvma_end-dvma_base)) != dvma_base)
                    252:                panic("unable to allocate from DVMA map");
                    253:        dvmamap_extent = extent_create("dvmamap", dvma_base, dvma_end,
                    254:                                       M_DEVBUF, NULL, 0, EX_NOWAIT);
                    255:        if (dvmamap_extent == 0)
                    256:                panic("unable to allocate extent for dvma");
                    257:
                    258: #ifdef DEBUG
                    259:        pmapdebug = opmapdebug;
                    260: #endif
                    261:        printf("avail mem = %lu (%luMB)\n", ptoa(uvmexp.free),
                    262:            ptoa(uvmexp.free)/1024/1024);
                    263:
                    264:        /*
                    265:         * Set up buffers, so they can be used to read disk labels.
                    266:         */
                    267:        bufinit();
                    268:
                    269:        /* Early interrupt handlers initialization */
                    270:        intr_init();
                    271: }
                    272:
                    273: /*
                    274:  * Allocate space for system data structures.  We are given
                    275:  * a starting virtual address and we return a final virtual
                    276:  * address; along the way we set each data structure pointer.
                    277:  *
                    278:  * You call allocsys() with 0 to find out how much space we want,
                    279:  * allocate that much and fill it with zeroes, and then call
                    280:  * allocsys() again with the correct base virtual address.
                    281:  */
                    282: caddr_t
                    283: allocsys(v)
                    284:        caddr_t v;
                    285: {
                    286:
                    287: #define        valloc(name, type, num) \
                    288:            v = (caddr_t)(((name) = (type *)v) + (num))
                    289: #ifdef SYSVMSG
                    290:        valloc(msgpool, char, msginfo.msgmax);
                    291:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
                    292:        valloc(msghdrs, struct msg, msginfo.msgtql);
                    293:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
                    294: #endif
                    295:
                    296:        return (v);
                    297: }
                    298:
                    299: /*
                    300:  * Set up registers on exec.
                    301:  *
                    302:  * XXX this entire mess must be fixed
                    303:  */
                    304: /* ARGSUSED */
                    305: void
                    306: setregs(p, pack, stack, retval)
                    307:        struct proc *p;
                    308:        struct exec_package *pack;
                    309:        u_long stack;
                    310:        register_t *retval;
                    311: {
                    312:        struct trapframe *tf = p->p_md.md_tf;
                    313:        struct fpstate *fs;
                    314:        int psr;
                    315:
                    316:        /*
                    317:         * Setup the process StackGhost cookie which will be XORed into
                    318:         * the return pointer as register windows are over/underflowed
                    319:         */
                    320:        p->p_addr->u_pcb.pcb_wcookie = arc4random();
                    321:
                    322:        /* The cookie needs to guarantee invalid alignment after the XOR */
                    323:        switch (p->p_addr->u_pcb.pcb_wcookie % 3) {
                    324:        case 0: /* Two lsb's already both set except if the cookie is 0 */
                    325:                p->p_addr->u_pcb.pcb_wcookie |= 0x3;
                    326:                break;
                    327:        case 1: /* Set the lsb */
                    328:                p->p_addr->u_pcb.pcb_wcookie = 1 |
                    329:                        (p->p_addr->u_pcb.pcb_wcookie & ~0x3);
                    330:                break;
                    331:        case 2: /* Set the second most lsb */
                    332:                p->p_addr->u_pcb.pcb_wcookie = 2 |
                    333:                        (p->p_addr->u_pcb.pcb_wcookie & ~0x3);
                    334:                break;
                    335:        }
                    336:
                    337:        /* Don't allow misaligned code by default */
                    338:        p->p_md.md_flags &= ~MDP_FIXALIGN;
                    339:
                    340:        /*
                    341:         * The syscall will ``return'' to npc or %g7 or %g2; set them all.
                    342:         * Set the rest of the registers to 0 except for %o6 (stack pointer,
                    343:         * built in exec()) and psr (retain CWP and PSR_S bits).
                    344:         */
                    345:        psr = tf->tf_psr & (PSR_S | PSR_CWP);
                    346:        if ((fs = p->p_md.md_fpstate) != NULL) {
                    347:                /*
                    348:                 * We hold an FPU state.  If we own *the* FPU chip state
                    349:                 * we must get rid of it, and the only way to do that is
                    350:                 * to save it.  In any case, get rid of our FPU state.
                    351:                 */
                    352:                if (p == cpuinfo.fpproc) {
                    353:                        savefpstate(fs);
                    354:                        cpuinfo.fpproc = NULL;
                    355:                }
                    356:                free((void *)fs, M_SUBPROC);
                    357:                p->p_md.md_fpstate = NULL;
                    358:        }
                    359:        bzero((caddr_t)tf, sizeof *tf);
                    360:        tf->tf_psr = psr;
                    361:        tf->tf_npc = pack->ep_entry & ~3;
                    362:        tf->tf_global[1] = (int)PS_STRINGS;
                    363:        tf->tf_global[2] = tf->tf_global[7] = tf->tf_npc;
                    364:        /* XXX exec of init(8) returns via proc_trampoline() */
                    365:        if (p->p_pid == 1) {
                    366:                tf->tf_pc = tf->tf_npc;
                    367:                tf->tf_npc += 4;
                    368:        }
                    369:        stack -= sizeof(struct rwindow);
                    370:        tf->tf_out[6] = stack;
                    371:        retval[1] = 0;
                    372: }
                    373:
                    374: #ifdef DEBUG
                    375: int sigdebug = 0;
                    376: int sigpid = 0;
                    377: #define SDB_FOLLOW     0x01
                    378: #define SDB_KSTACK     0x02
                    379: #define SDB_FPSTATE    0x04
                    380: #endif
                    381:
                    382: struct sigframe {
                    383:        int     sf_signo;               /* signal number */
                    384:        siginfo_t *sf_sip;              /* points to siginfo_t */
                    385: #ifdef COMPAT_SUNOS
                    386:        struct  sigcontext *sf_scp;     /* points to user addr of sigcontext */
                    387: #else
                    388:        int     sf_xxx;                 /* placeholder */
                    389: #endif
                    390:        caddr_t sf_addr;                /* SunOS compat */
                    391:        struct  sigcontext sf_sc;       /* actual sigcontext */
                    392:        siginfo_t sf_si;
                    393: };
                    394:
                    395: /*
                    396:  * machine dependent system variables.
                    397:  */
                    398: int
                    399: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
                    400:        int *name;
                    401:        u_int namelen;
                    402:        void *oldp;
                    403:        size_t *oldlenp;
                    404:        void *newp;
                    405:        size_t newlen;
                    406:        struct proc *p;
                    407: {
                    408: #if (NLED > 0) || (NAUXREG > 0) || (NSCF > 0)
                    409:        int oldval;
                    410: #endif
                    411:        int ret;
                    412:        extern int v8mul;
                    413:
                    414:        /* all sysctl names are this level are terminal */
                    415:        if (namelen != 1)
                    416:                return (ENOTDIR);       /* overloaded */
                    417:
                    418:        switch (name[0]) {
                    419:        case CPU_LED_BLINK:
                    420: #if (NLED > 0) || (NAUXREG > 0) || (NSCF > 0)
                    421:                oldval = sparc_led_blink;
                    422:                ret = sysctl_int(oldp, oldlenp, newp, newlen,
                    423:                    &sparc_led_blink);
                    424:
                    425:                /*
                    426:                 * If we were false and are now true, call led_blink().
                    427:                 * led_blink() itself will catch the other case.
                    428:                 */
                    429:                if (!oldval && sparc_led_blink > oldval) {
                    430: #if NAUXREG > 0
                    431:                        led_blink((caddr_t *)0);
                    432: #endif
                    433: #if NLED > 0
                    434:                        led_cycle((caddr_t *)led_sc);
                    435: #endif
                    436: #if NSCF > 0
                    437:                        scfblink((caddr_t *)0);
                    438: #endif
                    439:                }
                    440:
                    441:                return (ret);
                    442: #else
                    443:                return (EOPNOTSUPP);
                    444: #endif
                    445:        case CPU_CPUTYPE:
                    446:                return (sysctl_rdint(oldp, oldlenp, newp, cputyp));
                    447:        case CPU_V8MUL:
                    448:                return (sysctl_rdint(oldp, oldlenp, newp, v8mul));
                    449:        default:
                    450:                return (EOPNOTSUPP);
                    451:        }
                    452:        /* NOTREACHED */
                    453: }
                    454:
                    455: /*
                    456:  * Send an interrupt to process.
                    457:  */
                    458: void
                    459: sendsig(catcher, sig, mask, code, type, val)
                    460:        sig_t catcher;
                    461:        int sig, mask;
                    462:        u_long code;
                    463:        int type;
                    464:        union sigval val;
                    465: {
                    466:        struct proc *p = curproc;
                    467:        struct sigacts *psp = p->p_sigacts;
                    468:        struct sigframe *fp;
                    469:        struct trapframe *tf;
                    470:        int caddr, oonstack, oldsp, newsp;
                    471:        struct sigframe sf;
                    472: #ifdef COMPAT_SUNOS
                    473:        extern struct emul emul_sunos;
                    474: #endif
                    475:
                    476:        tf = p->p_md.md_tf;
                    477:        oldsp = tf->tf_out[6];
                    478:        oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
                    479:        /*
                    480:         * Compute new user stack addresses, subtract off
                    481:         * one signal frame, and align.
                    482:         */
                    483:        if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
                    484:            (psp->ps_sigonstack & sigmask(sig))) {
                    485:                fp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
                    486:                                         psp->ps_sigstk.ss_size);
                    487:                psp->ps_sigstk.ss_flags |= SS_ONSTACK;
                    488:        } else
                    489:                fp = (struct sigframe *)oldsp;
                    490:        fp = (struct sigframe *)((int)(fp - 1) & ~7);
                    491:
                    492: #ifdef DEBUG
                    493:        if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
                    494:                printf("sendsig: %s[%d] sig %d newusp %p scp %p\n",
                    495:                    p->p_comm, p->p_pid, sig, fp, &fp->sf_sc);
                    496: #endif
                    497:        /*
                    498:         * Now set up the signal frame.  We build it in kernel space
                    499:         * and then copy it out.  We probably ought to just build it
                    500:         * directly in user space....
                    501:         */
                    502:        sf.sf_signo = sig;
                    503:        sf.sf_sip = NULL;
                    504: #ifdef COMPAT_SUNOS
                    505:        if (p->p_emul == &emul_sunos) {
                    506:                sf.sf_sip = (void *)code;       /* SunOS has "int code" */
                    507:                sf.sf_scp = &fp->sf_sc;
                    508:                sf.sf_addr = val.sival_ptr;
                    509:        }
                    510: #endif
                    511:
                    512:        /*
                    513:         * Build the signal context to be used by sigreturn.
                    514:         */
                    515:        sf.sf_sc.sc_onstack = oonstack;
                    516:        sf.sf_sc.sc_mask = mask;
                    517:        sf.sf_sc.sc_sp = oldsp;
                    518:        sf.sf_sc.sc_pc = tf->tf_pc;
                    519:        sf.sf_sc.sc_npc = tf->tf_npc;
                    520:        sf.sf_sc.sc_psr = tf->tf_psr;
                    521:        sf.sf_sc.sc_g1 = tf->tf_global[1];
                    522:        sf.sf_sc.sc_o0 = tf->tf_out[0];
                    523:
                    524:        if (psp->ps_siginfo & sigmask(sig)) {
                    525:                sf.sf_sip = &fp->sf_si;
                    526:                initsiginfo(&sf.sf_si, sig, code, type, val);
                    527:        }
                    528:
                    529:        /*
                    530:         * Put the stack in a consistent state before we whack away
                    531:         * at it.  Note that write_user_windows may just dump the
                    532:         * registers into the pcb; we need them in the process's memory.
                    533:         * We also need to make sure that when we start the signal handler,
                    534:         * its %i6 (%fp), which is loaded from the newly allocated stack area,
                    535:         * joins seamlessly with the frame it was in when the signal occurred,
                    536:         * so that the debugger and _longjmp code can back up through it.
                    537:         */
                    538:        newsp = (int)fp - sizeof(struct rwindow);
                    539:        write_user_windows();
                    540:        /* XXX do not copyout siginfo if not needed */
                    541:        if (rwindow_save(p) || copyout((caddr_t)&sf, (caddr_t)fp, sizeof sf) ||
                    542:            copyout(&oldsp, &((struct rwindow *)newsp)->rw_in[6],
                    543:              sizeof(register_t)) != 0) {
                    544:                /*
                    545:                 * Process has trashed its stack; give it an illegal
                    546:                 * instruction to halt it in its tracks.
                    547:                 */
                    548: #ifdef DEBUG
                    549:                if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
                    550:                        printf("sendsig: window save or copyout error\n");
                    551: #endif
                    552:                sigexit(p, SIGILL);
                    553:                /* NOTREACHED */
                    554:        }
                    555: #ifdef DEBUG
                    556:        if (sigdebug & SDB_FOLLOW)
                    557:                printf("sendsig: %s[%d] sig %d scp %p\n",
                    558:                       p->p_comm, p->p_pid, sig, &fp->sf_sc);
                    559: #endif
                    560:        /*
                    561:         * Arrange to continue execution at the code copied out in exec().
                    562:         * It needs the function to call in %g1, and a new stack pointer.
                    563:         */
                    564: #ifdef COMPAT_SUNOS
                    565:        if (psp->ps_usertramp & sigmask(sig)) {
                    566:                caddr = (int)catcher;   /* user does his own trampolining */
                    567:        } else
                    568: #endif
                    569:        {
                    570:                caddr = p->p_sigcode;
                    571:                tf->tf_global[1] = (int)catcher;
                    572:        }
                    573:        tf->tf_pc = caddr;
                    574:        tf->tf_npc = caddr + 4;
                    575:        tf->tf_out[6] = newsp;
                    576: #ifdef DEBUG
                    577:        if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
                    578:                printf("sendsig: about to return to catcher\n");
                    579: #endif
                    580: }
                    581:
                    582: /*
                    583:  * System call to cleanup state after a signal
                    584:  * has been taken.  Reset signal mask and
                    585:  * stack state from context left by sendsig (above),
                    586:  * and return to the given trap frame (if there is one).
                    587:  * Check carefully to make sure that the user has not
                    588:  * modified the state to gain improper privileges or to cause
                    589:  * a machine fault.
                    590:  */
                    591: /* ARGSUSED */
                    592: int
                    593: sys_sigreturn(p, v, retval)
                    594:        struct proc *p;
                    595:        void *v;
                    596:        register_t *retval;
                    597: {
                    598:        struct sys_sigreturn_args /* {
                    599:                syscallarg(struct sigcontext *) sigcntxp;
                    600:        } */ *uap = v;
                    601:        struct sigcontext ksc;
                    602:        struct trapframe *tf;
                    603:        int error;
                    604:
                    605:        /* First ensure consistent stack state (see sendsig). */
                    606:        write_user_windows();
                    607:        if (rwindow_save(p))
                    608:                sigexit(p, SIGILL);
                    609: #ifdef DEBUG
                    610:        if (sigdebug & SDB_FOLLOW)
                    611:                printf("sigreturn: %s[%d], sigcntxp %p\n",
                    612:                    p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
                    613: #endif
                    614:        if ((error = copyin(SCARG(uap, sigcntxp), &ksc, sizeof(ksc))) != 0)
                    615:                return (error);
                    616:        tf = p->p_md.md_tf;
                    617:        /*
                    618:         * Only the icc bits in the psr are used, so it need not be
                    619:         * verified.  pc and npc must be multiples of 4.  This is all
                    620:         * that is required; if it holds, just do it.
                    621:         */
                    622:        if (((ksc.sc_pc | ksc.sc_npc) & 3) != 0)
                    623:                return (EINVAL);
                    624:        /* take only psr ICC field */
                    625:        tf->tf_psr = (tf->tf_psr & ~PSR_ICC) | (ksc.sc_psr & PSR_ICC);
                    626:        tf->tf_pc = ksc.sc_pc;
                    627:        tf->tf_npc = ksc.sc_npc;
                    628:        tf->tf_global[1] = ksc.sc_g1;
                    629:        tf->tf_out[0] = ksc.sc_o0;
                    630:        tf->tf_out[6] = ksc.sc_sp;
                    631:        if (ksc.sc_onstack & 1)
                    632:                p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
                    633:        else
                    634:                p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
                    635:        p->p_sigmask = ksc.sc_mask & ~sigcantmask;
                    636:        return (EJUSTRETURN);
                    637: }
                    638:
                    639: int    waittime = -1;
                    640:
                    641: void
                    642: boot(howto)
                    643:        int howto;
                    644: {
                    645:        int i;
                    646:        static char str[4];     /* room for "-sd\0" */
                    647:
                    648:        /* If system is cold, just halt. */
                    649:        if (cold) {
                    650:                /* (Unless the user explicitly asked for reboot.) */
                    651:                if ((howto & RB_USERREQ) == 0)
                    652:                        howto |= RB_HALT;
                    653:                goto haltsys;
                    654:        }
                    655:
                    656:        fb_unblank();
                    657:        boothowto = howto;
                    658:        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
                    659:                extern struct proc proc0;
                    660:
                    661:                /* XXX protect against curproc->p_stats.foo refs in sync() */
                    662:                if (curproc == NULL)
                    663:                        curproc = &proc0;
                    664:                waittime = 0;
                    665:                vfs_shutdown();
                    666:
                    667:                /*
                    668:                 * If we've been adjusting the clock, the todr
                    669:                 * will be out of synch; adjust it now unless
                    670:                 * the system was sitting in ddb.
                    671:                 */
                    672:                if ((howto & RB_TIMEBAD) == 0) {
                    673:                        resettodr();
                    674:                } else {
                    675:                        printf("WARNING: not updating battery clock\n");
                    676:                }
                    677:        }
                    678:        (void) splhigh();               /* ??? */
                    679:
                    680:        if (howto & RB_DUMP)
                    681:                dumpsys();
                    682:
                    683: haltsys:
                    684:        /* Run any shutdown hooks */
                    685:        doshutdownhooks();
                    686:
                    687:        if ((howto & RB_HALT) || (howto & RB_POWERDOWN)) {
                    688: #if defined(SUN4M)
                    689:                if (howto & RB_POWERDOWN) {
                    690:                        printf("attempting to power down...\n");
                    691: #if NTCTRL > 0
                    692:                        tadpole_powerdown();
                    693: #endif
                    694: #if NPOWER > 0
                    695:                        auxio_powerdown();
                    696: #endif
                    697:                        rominterpret("power-off");
                    698:                        printf("WARNING: powerdown failed!\n");
                    699:                }
                    700: #endif /* SUN4M */
                    701:                printf("halted\n\n");
                    702:                romhalt();
                    703:        }
                    704:
                    705:        printf("rebooting\n\n");
                    706:        i = 1;
                    707:        if (howto & RB_SINGLE)
                    708:                str[i++] = 's';
                    709:        if (howto & RB_KDB)
                    710:                str[i++] = 'd';
                    711:        if (i > 1) {
                    712:                str[0] = '-';
                    713:                str[i] = 0;
                    714:        } else
                    715:                str[0] = 0;
                    716:        romboot(str);
                    717:        /*NOTREACHED*/
                    718: }
                    719:
                    720: /* XXX - dumpmag not eplicitly used, savecore may search for it to get here */
                    721: u_long dumpmag = 0x8fca0101;   /* magic number for savecore */
                    722: int    dumpsize = 0;           /* also for savecore */
                    723: long   dumplo = 0;
                    724:
                    725: void
                    726: dumpconf(void)
                    727: {
                    728:        int nblks, dumpblks;
                    729:
                    730:        if (dumpdev == NODEV ||
                    731:            (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
                    732:                return;
                    733:        if (nblks <= ctod(1))
                    734:                return;
                    735:
                    736:        dumpblks = ctod(physmem) + ctod(pmap_dumpsize());
                    737:        if (dumpblks > (nblks - ctod(1)))
                    738:                /*
                    739:                 * dump size is too big for the partition.
                    740:                 * Note, we safeguard a click at the front for a
                    741:                 * possible disk label.
                    742:                 */
                    743:                return;
                    744:
                    745:        /* Put the dump at the end of the partition */
                    746:        dumplo = nblks - dumpblks;
                    747:
                    748:        /*
                    749:         * savecore(8) expects dumpsize to be the number of pages
                    750:         * of actual core dumped (i.e. excluding the MMU stuff).
                    751:         */
                    752:        dumpsize = physmem;
                    753: }
                    754:
                    755: #define        BYTES_PER_DUMP  (32 * 1024)     /* must be a multiple of pagesize */
                    756: static vaddr_t dumpspace;
                    757:
                    758: /*
                    759:  * Allocate the dump i/o buffer area during kernel memory allocation
                    760:  */
                    761: caddr_t
                    762: reserve_dumppages(p)
                    763:        caddr_t p;
                    764: {
                    765:
                    766:        dumpspace = (vaddr_t)p;
                    767:        return (p + BYTES_PER_DUMP);
                    768: }
                    769:
                    770: /*
                    771:  * Write a crash dump.
                    772:  */
                    773: void
                    774: dumpsys()
                    775: {
                    776:        int psize;
                    777:        daddr64_t blkno;
                    778:        int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
                    779:        int error = 0;
                    780:        struct memarr *mp;
                    781:        int nmem;
                    782:        extern struct memarr pmemarr[];
                    783:        extern int npmemarr;
                    784:
                    785:        /* copy registers to memory */
                    786:        snapshot(cpcb);
                    787:        stackdump();
                    788:
                    789:        if (dumpdev == NODEV)
                    790:                return;
                    791:
                    792:        /*
                    793:         * For dumps during autoconfiguration,
                    794:         * if dump device has already configured...
                    795:         */
                    796:        if (dumpsize == 0)
                    797:                dumpconf();
                    798:        if (dumplo <= 0)
                    799:                return;
                    800:        printf("\ndumping to dev(%d,%d), at offset %ld blocks\n",
                    801:            major(dumpdev), minor(dumpdev), dumplo);
                    802:
                    803:        psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
                    804:        printf("dump ");
                    805:        if (psize == -1) {
                    806:                printf("area unavailable\n");
                    807:                return;
                    808:        }
                    809:        blkno = dumplo;
                    810:        dump = bdevsw[major(dumpdev)].d_dump;
                    811:
                    812:        printf("mmu ");
                    813:        error = pmap_dumpmmu(dump, blkno);
                    814:        blkno += ctod(pmap_dumpsize());
                    815:
                    816:        printf("memory ");
                    817:        for (mp = pmemarr, nmem = npmemarr; --nmem >= 0 && error == 0; mp++) {
                    818:                unsigned i = 0, n;
                    819:                unsigned maddr = mp->addr;
                    820:
                    821:                /* XXX - what's so special about PA 0 that we can't dump it? */
                    822:                if (maddr == 0) {
                    823:                        /* Skip first page at physical address 0 */
                    824:                        maddr += NBPG;
                    825:                        i += NBPG;
                    826:                        blkno += btodb(NBPG);
                    827:                }
                    828:
                    829:                printf("@0x%x:", maddr);
                    830:
                    831:                for (; i < mp->len; i += n) {
                    832:                        n = mp->len - i;
                    833:                        if (n > BYTES_PER_DUMP)
                    834:                                 n = BYTES_PER_DUMP;
                    835:
                    836:                        /* print out which MBs we are dumping */
                    837:                        if (i % (1024*1024) <= NBPG)
                    838:                                printf("%d ", i / (1024*1024));
                    839:
                    840:                        (void) pmap_map(dumpspace, maddr, maddr + n,
                    841:                                        VM_PROT_READ);
                    842:                        error = (*dump)(dumpdev, blkno,
                    843:                                        (caddr_t)dumpspace, (int)n);
                    844:                        pmap_remove(pmap_kernel(), dumpspace, dumpspace + n);
                    845:                        if (error)
                    846:                                break;
                    847:                        maddr += n;
                    848:                        blkno += btodb(n);
                    849:                }
                    850:        }
                    851:
                    852:        switch (error) {
                    853:
                    854:        case ENXIO:
                    855:                printf("device bad\n");
                    856:                break;
                    857:
                    858:        case EFAULT:
                    859:                printf("device not ready\n");
                    860:                break;
                    861:
                    862:        case EINVAL:
                    863:                printf("area improper\n");
                    864:                break;
                    865:
                    866:        case EIO:
                    867:                printf("i/o error\n");
                    868:                break;
                    869:
                    870:        case 0:
                    871:                printf("succeeded\n");
                    872:                break;
                    873:
                    874:        default:
                    875:                printf("error %d\n", error);
                    876:                break;
                    877:        }
                    878: }
                    879:
                    880: /*
                    881:  * get the fp and dump the stack as best we can.  don't leave the
                    882:  * current stack page
                    883:  */
                    884: void
                    885: stackdump()
                    886: {
                    887:        struct frame *fp = getfp(), *sfp;
                    888:
                    889:        sfp = fp;
                    890:        printf("Frame pointer is at %p\n", fp);
                    891:        printf("Call traceback:\n");
                    892:        while (fp && ((u_long)fp >> PGSHIFT) == ((u_long)sfp >> PGSHIFT)) {
                    893:                printf("  pc = 0x%x  args = (0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) fp = %p\n",
                    894:                    fp->fr_pc, fp->fr_arg[0], fp->fr_arg[1], fp->fr_arg[2],
                    895:                    fp->fr_arg[3], fp->fr_arg[4], fp->fr_arg[5], fp->fr_arg[6],
                    896:                    fp->fr_fp);
                    897:                fp = fp->fr_fp;
                    898:        }
                    899: }
                    900:
                    901: /*
                    902:  * Map an I/O device given physical address and size in bytes, e.g.,
                    903:  *
                    904:  *     mydev = (struct mydev *)mapdev(myioaddr, 0,
                    905:  *                                    0, sizeof(struct mydev));
                    906:  *
                    907:  * See also machine/autoconf.h.
                    908:  *
                    909:  * XXXART - verify types (too tired now).
                    910:  */
                    911: void *
                    912: mapdev(phys, virt, offset, size)
                    913:        struct rom_reg *phys;
                    914:        int offset, virt, size;
                    915: {
                    916:        vaddr_t va;
                    917:        paddr_t pa, base;
                    918:        void *ret;
                    919:        static vaddr_t iobase;
                    920:        unsigned int pmtype;
                    921:
                    922:        if (iobase == NULL)
                    923:                iobase = IODEV_BASE;
                    924:
                    925:        base = (paddr_t)phys->rr_paddr + offset;
                    926:        if (virt != 0) {
                    927:                va = trunc_page(virt);
                    928:                size = round_page(virt + size) - va;
                    929:        } else {
                    930:                size = round_page(base + size) - trunc_page(base);
                    931:                va = iobase;
                    932:                iobase += size;
                    933:                if (iobase > IODEV_END) /* unlikely */
                    934:                        panic("mapiodev");
                    935:        }
                    936:        if (size == 0)
                    937:                panic("mapdev: zero size");
                    938:
                    939:        ret = (void *)(va | (base & PGOFSET));
                    940:                        /* note: preserve page offset */
                    941:
                    942:        pa = trunc_page(base);
                    943:        pmtype = PMAP_IOENC(phys->rr_iospace);
                    944:
                    945:        do {
                    946:                pmap_kenter_pa(va, pa | pmtype | PMAP_NC,
                    947:                    VM_PROT_READ | VM_PROT_WRITE);
                    948:                va += PAGE_SIZE;
                    949:                pa += PAGE_SIZE;
                    950:        } while ((size -= PAGE_SIZE) > 0);
                    951:        pmap_update(pmap_kernel());
                    952:        return (ret);
                    953: }
                    954:
                    955: #ifdef COMPAT_SUNOS
                    956: int
                    957: cpu_exec_aout_makecmds(p, epp)
                    958:        struct proc *p;
                    959:        struct exec_package *epp;
                    960: {
                    961:        int error = ENOEXEC;
                    962:
                    963:        extern int sunos_exec_aout_makecmds(struct proc *, struct exec_package *);
                    964:        if ((error = sunos_exec_aout_makecmds(p, epp)) == 0)
                    965:                return 0;
                    966:        return error;
                    967: }
                    968: #endif
                    969:
                    970: #ifdef SUN4
                    971: void
                    972: oldmon_w_trace(va)
                    973:        u_long va;
                    974: {
                    975:        u_long stop;
                    976:        struct frame *fp;
                    977:
                    978:        if (curproc)
                    979:                printf("curproc = %p, pid %d\n", curproc, curproc->p_pid);
                    980:        else
                    981:                printf("no curproc\n");
                    982:        printf("uvm: swtch %d, trap %d, sys %d, intr %d, soft %d, faults %d\n",
                    983:               uvmexp.swtch, uvmexp.traps, uvmexp.syscalls, uvmexp.intrs,
                    984:               uvmexp.softs, uvmexp.faults);
                    985:        write_user_windows();
                    986:
                    987:        printf("\nstack trace with sp = 0x%lx\n", va);
                    988:        stop = round_page(va);
                    989:        printf("stop at 0x%lx\n", stop);
                    990:        fp = (struct frame *) va;
                    991:        while (round_page((u_long) fp) == stop) {
                    992:                printf("  0x%x(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) fp %p\n", fp->fr_pc,
                    993:                    fp->fr_arg[0], fp->fr_arg[1], fp->fr_arg[2], fp->fr_arg[3],
                    994:                    fp->fr_arg[4], fp->fr_arg[5], fp->fr_arg[6], fp->fr_fp);
                    995:                fp = fp->fr_fp;
                    996:                if (fp == NULL)
                    997:                        break;
                    998:        }
                    999:        printf("end of stack trace\n");
                   1000: }
                   1001:
                   1002: void
                   1003: oldmon_w_cmd(va, ar)
                   1004:        u_long va;
                   1005:        char *ar;
                   1006: {
                   1007:        switch (*ar) {
                   1008:        case '\0':
                   1009:                switch (va) {
                   1010:                case 0:
                   1011:                        panic("g0 panic");
                   1012:                case 4:
                   1013:                        printf("w: case 4\n");
                   1014:                        break;
                   1015:                default:
                   1016:                        printf("w: unknown case %ld\n", va);
                   1017:                        break;
                   1018:                }
                   1019:                break;
                   1020:        case 't':
                   1021:                oldmon_w_trace(va);
                   1022:                break;
                   1023:        default:
                   1024:                printf("w: arg not allowed\n");
                   1025:        }
                   1026: }
                   1027:
                   1028: int
                   1029: ldcontrolb(addr)
                   1030: caddr_t addr;
                   1031: {
                   1032:        struct pcb *xpcb;
                   1033:        extern struct user *proc0paddr;
                   1034:        u_long saveonfault;
                   1035:        int res;
                   1036:        int s;
                   1037:
                   1038:        s = splhigh();
                   1039:        if (curproc == NULL)
                   1040:                xpcb = (struct pcb *)proc0paddr;
                   1041:        else
                   1042:                xpcb = &curproc->p_addr->u_pcb;
                   1043:
                   1044:        saveonfault = (u_long)xpcb->pcb_onfault;
                   1045:         res = xldcontrolb(addr, xpcb);
                   1046:        xpcb->pcb_onfault = (caddr_t)saveonfault;
                   1047:
                   1048:        splx(s);
                   1049:        return (res);
                   1050: }
                   1051: #endif /* SUN4 */

CVSweb