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

Annotation of sys/arch/sh/sh/sh_machdep.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: sh_machdep.c,v 1.16 2007/06/06 17:15:12 deraadt Exp $ */
        !             2: /*     $NetBSD: sh3_machdep.c,v 1.59 2006/03/04 01:13:36 uwe Exp $     */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 2007 Miodrag Vallat.
        !             6:  *
        !             7:  * Permission to use, copy, modify, and distribute this software for any
        !             8:  * purpose with or without fee is hereby granted, provided that the above
        !             9:  * copyright notice, this permission notice, and the disclaimer below
        !            10:  * appear in all copies.
        !            11:  *
        !            12:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            13:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            14:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            15:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            16:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            17:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            18:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            19:  */
        !            20: /*-
        !            21:  * Copyright (c) 1996, 1997, 1998, 2002 The NetBSD Foundation, Inc.
        !            22:  * All rights reserved.
        !            23:  *
        !            24:  * This code is derived from software contributed to The NetBSD Foundation
        !            25:  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
        !            26:  * Simulation Facility, NASA Ames Research Center.
        !            27:  *
        !            28:  * Redistribution and use in source and binary forms, with or without
        !            29:  * modification, are permitted provided that the following conditions
        !            30:  * are met:
        !            31:  * 1. Redistributions of source code must retain the above copyright
        !            32:  *    notice, this list of conditions and the following disclaimer.
        !            33:  * 2. Redistributions in binary form must reproduce the above copyright
        !            34:  *    notice, this list of conditions and the following disclaimer in the
        !            35:  *    documentation and/or other materials provided with the distribution.
        !            36:  * 3. All advertising materials mentioning features or use of this software
        !            37:  *    must display the following acknowledgement:
        !            38:  *     This product includes software developed by the NetBSD
        !            39:  *     Foundation, Inc. and its contributors.
        !            40:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            41:  *    contributors may be used to endorse or promote products derived
        !            42:  *    from this software without specific prior written permission.
        !            43:  *
        !            44:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            45:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            46:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            47:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            48:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            49:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            50:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            51:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            52:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            53:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            54:  * POSSIBILITY OF SUCH DAMAGE.
        !            55:  */
        !            56: /*-
        !            57:  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
        !            58:  * All rights reserved.
        !            59:  *
        !            60:  * This code is derived from software contributed to Berkeley by
        !            61:  * William Jolitz.
        !            62:  *
        !            63:  * Redistribution and use in source and binary forms, with or without
        !            64:  * modification, are permitted provided that the following conditions
        !            65:  * are met:
        !            66:  * 1. Redistributions of source code must retain the above copyright
        !            67:  *    notice, this list of conditions and the following disclaimer.
        !            68:  * 2. Redistributions in binary form must reproduce the above copyright
        !            69:  *    notice, this list of conditions and the following disclaimer in the
        !            70:  *    documentation and/or other materials provided with the distribution.
        !            71:  * 3. Neither the name of the University nor the names of its contributors
        !            72:  *    may be used to endorse or promote products derived from this software
        !            73:  *    without specific prior written permission.
        !            74:  *
        !            75:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            76:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            77:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            78:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            79:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            80:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            81:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            82:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            83:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            84:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            85:  * SUCH DAMAGE.
        !            86:  *
        !            87:  *     @(#)machdep.c   7.4 (Berkeley) 6/3/91
        !            88:  */
        !            89:
        !            90: #include <sys/param.h>
        !            91: #include <sys/systm.h>
        !            92:
        !            93: #include <sys/buf.h>
        !            94: #include <sys/exec.h>
        !            95: #include <sys/kernel.h>
        !            96: #include <sys/malloc.h>
        !            97: #include <sys/mount.h>
        !            98: #include <sys/proc.h>
        !            99: #include <sys/signalvar.h>
        !           100: #include <sys/syscallargs.h>
        !           101: #include <sys/user.h>
        !           102: #include <sys/sched.h>
        !           103: #include <sys/msg.h>
        !           104: #include <sys/conf.h>
        !           105: #include <sys/core.h>
        !           106: #include <sys/kcore.h>
        !           107: #include <sys/reboot.h>
        !           108:
        !           109: #include <uvm/uvm_extern.h>
        !           110:
        !           111: #include <dev/cons.h>
        !           112:
        !           113: #include <sh/cache.h>
        !           114: #include <sh/clock.h>
        !           115: #include <sh/locore.h>
        !           116: #include <sh/mmu.h>
        !           117: #include <sh/trap.h>
        !           118: #include <sh/intr.h>
        !           119: #include <sh/kcore.h>
        !           120:
        !           121: #ifndef BUFCACHEPERCENT
        !           122: #define BUFCACHEPERCENT 5
        !           123: #endif
        !           124:
        !           125: #ifdef  BUFPAGES
        !           126: int    bufpages = BUFPAGES;
        !           127: #else
        !           128: int    bufpages = 0;
        !           129: #endif
        !           130: int    bufcachepercent = BUFCACHEPERCENT;
        !           131:
        !           132: /* Our exported CPU info; we can have only one. */
        !           133: int cpu_arch;
        !           134: int cpu_product;
        !           135: char cpu_model[120];
        !           136:
        !           137: struct vm_map *exec_map;
        !           138: struct vm_map *phys_map;
        !           139:
        !           140: int physmem;
        !           141: struct user *proc0paddr;       /* init_main.c use this. */
        !           142: struct pcb *curpcb;
        !           143: struct md_upte *curupte;       /* SH3 wired u-area hack */
        !           144:
        !           145: #define        VBR     (u_int8_t *)SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN)
        !           146: vaddr_t ram_start = SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN);
        !           147: /* exception handler holder (sh/sh/vectors.S) */
        !           148: extern char sh_vector_generic[], sh_vector_generic_end[];
        !           149: extern char sh_vector_interrupt[], sh_vector_interrupt_end[];
        !           150: #ifdef SH3
        !           151: extern char sh3_vector_tlbmiss[], sh3_vector_tlbmiss_end[];
        !           152: #endif
        !           153: #ifdef SH4
        !           154: extern char sh4_vector_tlbmiss[], sh4_vector_tlbmiss_end[];
        !           155: #endif
        !           156:
        !           157: caddr_t allocsys(caddr_t);
        !           158:
        !           159: /*
        !           160:  * These variables are needed by /sbin/savecore
        !           161:  */
        !           162: u_int32_t dumpmag = 0x8fca0101;        /* magic number */
        !           163: u_int dumpsize;                        /* pages */
        !           164: long dumplo;                   /* blocks */
        !           165: cpu_kcore_hdr_t cpu_kcore_hdr;
        !           166:
        !           167: void
        !           168: sh_cpu_init(int arch, int product)
        !           169: {
        !           170:        /* CPU type */
        !           171:        cpu_arch = arch;
        !           172:        cpu_product = product;
        !           173:
        !           174: #if defined(SH3) && defined(SH4)
        !           175:        /* Set register addresses */
        !           176:        sh_devreg_init();
        !           177: #endif
        !           178:        /* Cache access ops. */
        !           179:        sh_cache_init();
        !           180:
        !           181:        /* MMU access ops. */
        !           182:        sh_mmu_init();
        !           183:
        !           184:        /* Hardclock, RTC initialize. */
        !           185:        machine_clock_init();
        !           186:
        !           187:        /* ICU initiailze. */
        !           188:        intc_init();
        !           189:
        !           190:        /* Exception vector. */
        !           191:        memcpy(VBR + 0x100, sh_vector_generic,
        !           192:            sh_vector_generic_end - sh_vector_generic);
        !           193: #ifdef SH3
        !           194:        if (CPU_IS_SH3)
        !           195:                memcpy(VBR + 0x400, sh3_vector_tlbmiss,
        !           196:                    sh3_vector_tlbmiss_end - sh3_vector_tlbmiss);
        !           197: #endif
        !           198: #ifdef SH4
        !           199:        if (CPU_IS_SH4)
        !           200:                memcpy(VBR + 0x400, sh4_vector_tlbmiss,
        !           201:                    sh4_vector_tlbmiss_end - sh4_vector_tlbmiss);
        !           202: #endif
        !           203:        memcpy(VBR + 0x600, sh_vector_interrupt,
        !           204:            sh_vector_interrupt_end - sh_vector_interrupt);
        !           205:
        !           206:        if (!SH_HAS_UNIFIED_CACHE)
        !           207:                sh_icache_sync_all();
        !           208:
        !           209:        __asm volatile("ldc %0, vbr" :: "r"(VBR));
        !           210:
        !           211:        /* kernel stack setup */
        !           212:        __sh_switch_resume = CPU_IS_SH3 ? sh3_switch_resume : sh4_switch_resume;
        !           213:
        !           214:        /* Set page size (4KB) */
        !           215:        uvm_setpagesize();
        !           216: }
        !           217:
        !           218: /*
        !           219:  * void sh_proc0_init(void):
        !           220:  *     Setup proc0 u-area.
        !           221:  */
        !           222: void
        !           223: sh_proc0_init()
        !           224: {
        !           225:        struct switchframe *sf;
        !           226:        vaddr_t u;
        !           227:
        !           228:        /* Steal process0 u-area */
        !           229:        u = uvm_pageboot_alloc(USPACE);
        !           230:        memset((void *)u, 0, USPACE);
        !           231:
        !           232:        /* Setup proc0 */
        !           233:        proc0paddr = (struct user *)u;
        !           234:        proc0.p_addr = proc0paddr;
        !           235:        /*
        !           236:         * u-area map:
        !           237:         * |user| .... | .................. |
        !           238:         * | PAGE_SIZE | USPACE - PAGE_SIZE |
        !           239:          *        frame top        stack top
        !           240:         * current frame ... r6_bank
        !           241:         * stack top     ... r7_bank
        !           242:         * current stack ... r15
        !           243:         */
        !           244:        curpcb = proc0.p_md.md_pcb = &proc0.p_addr->u_pcb;
        !           245:        curupte = proc0.p_md.md_upte;
        !           246:
        !           247:        sf = &curpcb->pcb_sf;
        !           248:        sf->sf_r6_bank = u + PAGE_SIZE;
        !           249:        sf->sf_r7_bank = sf->sf_r15     = u + USPACE;
        !           250:        __asm volatile("ldc %0, r6_bank" :: "r"(sf->sf_r6_bank));
        !           251:        __asm volatile("ldc %0, r7_bank" :: "r"(sf->sf_r7_bank));
        !           252:
        !           253:        proc0.p_md.md_regs = (struct trapframe *)sf->sf_r6_bank - 1;
        !           254: #ifdef KSTACK_DEBUG
        !           255:        memset((char *)(u + sizeof(struct user)), 0x5a,
        !           256:            PAGE_SIZE - sizeof(struct user));
        !           257:        memset((char *)(u + PAGE_SIZE), 0xa5, USPACE - PAGE_SIZE);
        !           258: #endif /* KSTACK_DEBUG */
        !           259: }
        !           260:
        !           261: void
        !           262: sh_startup()
        !           263: {
        !           264:        vaddr_t minaddr, maxaddr;
        !           265:        caddr_t sysbase;
        !           266:        caddr_t size;
        !           267:
        !           268:        printf("%s", version);
        !           269:        if (*cpu_model != '\0')
        !           270:                printf("%s\n", cpu_model);
        !           271: #ifdef DEBUG
        !           272:        printf("general exception handler:\t%d byte\n",
        !           273:            sh_vector_generic_end - sh_vector_generic);
        !           274:        printf("TLB miss exception handler:\t%d byte\n",
        !           275: #if defined(SH3) && defined(SH4)
        !           276:            CPU_IS_SH3 ? sh3_vector_tlbmiss_end - sh3_vector_tlbmiss :
        !           277:            sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
        !           278: #elif defined(SH3)
        !           279:            sh3_vector_tlbmiss_end - sh3_vector_tlbmiss
        !           280: #elif defined(SH4)
        !           281:            sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
        !           282: #endif
        !           283:            );
        !           284:        printf("interrupt exception handler:\t%d byte\n",
        !           285:            sh_vector_interrupt_end - sh_vector_interrupt);
        !           286: #endif /* DEBUG */
        !           287:
        !           288:        printf("real mem = %u (%uK)\n", ctob(physmem), ctob(physmem) / 1024);
        !           289:
        !           290:        /*
        !           291:         * Find out how much space we need, allocate it,
        !           292:         * and then give everything true virtual addresses.
        !           293:         */
        !           294:        size = allocsys(NULL);
        !           295:        sysbase = (caddr_t)uvm_km_zalloc(kernel_map, round_page((vaddr_t)size));
        !           296:        if (sysbase == 0)
        !           297:                panic("sh_startup: no room for system tables; %d required",
        !           298:                    (u_int)size);
        !           299:        if ((caddr_t)((allocsys(sysbase) - sysbase)) != size)
        !           300:                panic("cpu_startup: system table size inconsistency");
        !           301:
        !           302:        /*
        !           303:         * Determine how many buffers to allocate.
        !           304:         * We allocate bufcachepercent% of memory for buffer space.
        !           305:         */
        !           306:        if (bufpages == 0)
        !           307:                bufpages = physmem * bufcachepercent / 100;
        !           308:
        !           309:        /* Restrict to at most 25% filled kvm */
        !           310:        if (bufpages >
        !           311:            (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
        !           312:                bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
        !           313:                    PAGE_SIZE / 4;
        !           314:
        !           315:        /*
        !           316:         * Allocate a submap for exec arguments.  This map effectively
        !           317:         * limits the number of processes exec'ing at any time.
        !           318:         */
        !           319:        minaddr = vm_map_min(kernel_map);
        !           320:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           321:            16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
        !           322:
        !           323:        /*
        !           324:         * Allocate a submap for physio
        !           325:         */
        !           326:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           327:            VM_PHYS_SIZE, 0, FALSE, NULL);
        !           328:
        !           329:        /*
        !           330:         * Set up buffers, so they can be used to read disk labels.
        !           331:         */
        !           332:        bufinit();
        !           333:
        !           334:        printf("avail mem = %u (%uK)\n", ptoa(uvmexp.free),
        !           335:            ptoa(uvmexp.free) / 1024);
        !           336:
        !           337:        if (boothowto & RB_CONFIG) {
        !           338: #ifdef BOOT_CONFIG
        !           339:                user_config();
        !           340: #else
        !           341:                printf("kernel does not support -c; continuing..\n");
        !           342: #endif
        !           343:        }
        !           344: }
        !           345:
        !           346: /*
        !           347:  * Allocate space for system data structures.  We are given
        !           348:  * a starting virtual address and we return a final virtual
        !           349:  * address; along the way we set each data structure pointer.
        !           350:  *
        !           351:  * We call allocsys() with 0 to find out how much space we want,
        !           352:  * allocate that much and fill it with zeroes, and then call
        !           353:  * allocsys() again with the correct base virtual address.
        !           354:  */
        !           355: caddr_t
        !           356: allocsys(caddr_t v)
        !           357: {
        !           358: #define        valloc(name, type, num) v = (caddr_t)(((name) = (type *)v) + (num))
        !           359:
        !           360: #ifdef SYSVMSG
        !           361:        valloc(msgpool, char, msginfo.msgmax);
        !           362:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
        !           363:        valloc(msghdrs, struct msg, msginfo.msgtql);
        !           364:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
        !           365: #endif
        !           366:
        !           367:        return v;
        !           368: }
        !           369:
        !           370: void
        !           371: dumpconf(void)
        !           372: {
        !           373:        cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
        !           374:        u_int dumpextra, totaldumpsize;         /* in disk blocks */
        !           375:        u_int seg, nblks;
        !           376:
        !           377:        if (dumpdev == NODEV ||
        !           378:            (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
        !           379:                return;
        !           380:        if (nblks <= ctod(1))
        !           381:                return;
        !           382:
        !           383:        dumpsize = 0;
        !           384:        for (seg = 0; seg < h->kcore_nsegs; seg++)
        !           385:                dumpsize += atop(h->kcore_segs[seg].size);
        !           386:        dumpextra = cpu_dumpsize();
        !           387:
        !           388:        /* Always skip the first block, in case there is a label there. */
        !           389:        if (dumplo < btodb(1));
        !           390:                dumplo = btodb(1);
        !           391:
        !           392:        /* Put dump at the end of the partition, and make it fit. */
        !           393:        totaldumpsize = ctod(dumpsize) + dumpextra;
        !           394:        if (totaldumpsize > nblks - dumplo) {
        !           395:                totaldumpsize = dbtob(nblks - dumplo);
        !           396:                dumpsize = dtoc(totaldumpsize - dumpextra);
        !           397:        }
        !           398:        if (dumplo < nblks - totaldumpsize)
        !           399:                dumplo = nblks - totaldumpsize;
        !           400: }
        !           401:
        !           402: void
        !           403: dumpsys()
        !           404: {
        !           405:        cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
        !           406:        daddr64_t blkno;
        !           407:        int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
        !           408:        u_int page = 0;
        !           409:        paddr_t dumppa;
        !           410:        u_int seg;
        !           411:        int rc;
        !           412:        extern int msgbufmapped;
        !           413:
        !           414:        /* Don't record dump messages in msgbuf. */
        !           415:        msgbufmapped = 0;
        !           416:
        !           417:        /* Make sure dump settings are valid. */
        !           418:        if (dumpdev == NODEV)
        !           419:                return;
        !           420:        if (dumpsize == 0) {
        !           421:                dumpconf();
        !           422:                if (dumpsize == 0)
        !           423:                        return;
        !           424:        }
        !           425:        if (dumplo <= 0) {
        !           426:                printf("\ndump to dev 0x%x not possible, not enough space\n",
        !           427:                    dumpdev);
        !           428:                return;
        !           429:        }
        !           430:
        !           431:        dump = bdevsw[major(dumpdev)].d_dump;
        !           432:        blkno = dumplo;
        !           433:
        !           434:        printf("\ndumping to dev 0x%x offset %ld\n", dumpdev, dumplo);
        !           435:
        !           436:        printf("dump ");
        !           437:
        !           438:        /* Write dump header */
        !           439:        rc = cpu_dump(dump, &blkno);
        !           440:        if (rc != 0)
        !           441:                goto bad;
        !           442:
        !           443:        for (seg = 0; seg < h->kcore_nsegs; seg++) {
        !           444:                u_int pagesleft;
        !           445:
        !           446:                pagesleft = atop(h->kcore_segs[seg].size);
        !           447:                dumppa = (paddr_t)h->kcore_segs[seg].start;
        !           448:
        !           449:                while (pagesleft != 0) {
        !           450:                        u_int npages;
        !           451:
        !           452: #define        NPGMB   atop(1024 * 1024)
        !           453:                        if (page != 0 && (page % NPGMB) == 0)
        !           454:                                printf("%u ", page / NPGMB);
        !           455:
        !           456:                        /* do not dump more than 1MB at once */
        !           457:                        npages = min(pagesleft, NPGMB);
        !           458: #undef NPGMB
        !           459:                        npages = min(npages, dumpsize);
        !           460:
        !           461:                        rc = (*dump)(dumpdev, blkno,
        !           462:                            (caddr_t)SH3_PHYS_TO_P2SEG(dumppa), ptoa(npages));
        !           463:                        if (rc != 0)
        !           464:                                goto bad;
        !           465:
        !           466:                        pagesleft -= npages;
        !           467:                        dumppa += ptoa(npages);
        !           468:                        page += npages;
        !           469:                        dumpsize -= npages;
        !           470:                        if (dumpsize == 0)
        !           471:                                goto bad;       /* if truncated dump */
        !           472:                        blkno += ctod(npages);
        !           473:                }
        !           474:        }
        !           475: bad:
        !           476:        switch (rc) {
        !           477:        case 0:
        !           478:                printf("succeeded\n");
        !           479:                break;
        !           480:        case ENXIO:
        !           481:                printf("device bad\n");
        !           482:                break;
        !           483:        case EFAULT:
        !           484:                printf("device not ready\n");
        !           485:                break;
        !           486:        case EINVAL:
        !           487:                printf("area improper\n");
        !           488:                break;
        !           489:        case EIO:
        !           490:                printf("I/O error\n");
        !           491:                break;
        !           492:        case EINTR:
        !           493:                printf("aborted\n");
        !           494:                break;
        !           495:        default:
        !           496:                printf("error %d\n", rc);
        !           497:                break;
        !           498:        }
        !           499:
        !           500:        /* make sure console can output our last message */
        !           501:        delay(1 * 1000 * 1000);
        !           502: }
        !           503:
        !           504: /*
        !           505:  * Signal frame.
        !           506:  */
        !           507: struct sigframe {
        !           508: #if 0 /* in registers on entry to signal trampoline */
        !           509:        int             sf_signum;      /* r4 - "signum" argument for handler */
        !           510:        siginfo_t       *sf_sip;        /* r5 - "sip" argument for handler */
        !           511:        struct sigcontext *sf_ucp;      /* r6 - "ucp" argument for handler */
        !           512: #endif
        !           513:        struct sigcontext sf_uc;        /* actual context */
        !           514:        siginfo_t       sf_si;
        !           515: };
        !           516:
        !           517: /*
        !           518:  * Send an interrupt to process.
        !           519:  */
        !           520: void
        !           521: sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
        !           522:     union sigval val)
        !           523: {
        !           524:        struct proc *p = curproc;
        !           525:        struct sigframe *fp, frame;
        !           526:        struct trapframe *tf = p->p_md.md_regs;
        !           527:        struct sigacts *ps = p->p_sigacts;
        !           528:        siginfo_t *sip;
        !           529:        int onstack;
        !           530:
        !           531:        onstack = ps->ps_sigstk.ss_flags & SS_ONSTACK;
        !           532:        if ((ps->ps_flags & SAS_ALTSTACK) && onstack == 0 &&
        !           533:            (ps->ps_sigonstack & sigmask(sig))) {
        !           534:                fp = (struct sigframe *)((vaddr_t)ps->ps_sigstk.ss_sp +
        !           535:                    ps->ps_sigstk.ss_size);
        !           536:                ps->ps_sigstk.ss_flags |= SS_ONSTACK;
        !           537:        } else
        !           538:                fp = (void *)p->p_md.md_regs->tf_r15;
        !           539:        --fp;
        !           540:
        !           541:
        !           542:        bzero(&frame, sizeof(frame));
        !           543:
        !           544:        if (ps->ps_siginfo & sigmask(sig)) {
        !           545:                initsiginfo(&frame.sf_si, sig, code, type, val);
        !           546:                sip = &fp->sf_si;
        !           547:        } else
        !           548:                sip = NULL;
        !           549:
        !           550:        /* Save register context. */
        !           551:        frame.sf_uc.sc_reg.r_spc = tf->tf_spc;
        !           552:        frame.sf_uc.sc_reg.r_ssr = tf->tf_ssr;
        !           553:        frame.sf_uc.sc_reg.r_pr = tf->tf_pr;
        !           554:        frame.sf_uc.sc_reg.r_mach = tf->tf_mach;
        !           555:        frame.sf_uc.sc_reg.r_macl = tf->tf_macl;
        !           556:        frame.sf_uc.sc_reg.r_r15 = tf->tf_r15;
        !           557:        frame.sf_uc.sc_reg.r_r14 = tf->tf_r14;
        !           558:        frame.sf_uc.sc_reg.r_r13 = tf->tf_r13;
        !           559:        frame.sf_uc.sc_reg.r_r12 = tf->tf_r12;
        !           560:        frame.sf_uc.sc_reg.r_r11 = tf->tf_r11;
        !           561:        frame.sf_uc.sc_reg.r_r10 = tf->tf_r10;
        !           562:        frame.sf_uc.sc_reg.r_r9 = tf->tf_r9;
        !           563:        frame.sf_uc.sc_reg.r_r8 = tf->tf_r8;
        !           564:        frame.sf_uc.sc_reg.r_r7 = tf->tf_r7;
        !           565:        frame.sf_uc.sc_reg.r_r6 = tf->tf_r6;
        !           566:        frame.sf_uc.sc_reg.r_r5 = tf->tf_r5;
        !           567:        frame.sf_uc.sc_reg.r_r4 = tf->tf_r4;
        !           568:        frame.sf_uc.sc_reg.r_r3 = tf->tf_r3;
        !           569:        frame.sf_uc.sc_reg.r_r2 = tf->tf_r2;
        !           570:        frame.sf_uc.sc_reg.r_r1 = tf->tf_r1;
        !           571:        frame.sf_uc.sc_reg.r_r0 = tf->tf_r0;
        !           572: #ifdef SH4
        !           573:        if (CPU_IS_SH4)
        !           574:                fpu_save(&frame.sf_uc.sc_fpreg);
        !           575: #endif
        !           576:
        !           577:        frame.sf_uc.sc_onstack = onstack;
        !           578:        frame.sf_uc.sc_expevt = tf->tf_expevt;
        !           579:        /* frame.sf_uc.sc_err = 0; */
        !           580:        frame.sf_uc.sc_mask = mask;
        !           581:
        !           582:        if (copyout(&frame, fp, sizeof(frame)) != 0) {
        !           583:                /*
        !           584:                 * Process has trashed its stack; give it an illegal
        !           585:                 * instruction to halt it in its tracks.
        !           586:                 */
        !           587:                sigexit(p, SIGILL);
        !           588:                /* NOTREACHED */
        !           589:        }
        !           590:
        !           591:        tf->tf_r4 = sig;                /* "signum" argument for handler */
        !           592:        tf->tf_r5 = (int)sip;           /* "sip" argument for handler */
        !           593:        tf->tf_r6 = (int)&fp->sf_uc;    /* "ucp" argument for handler */
        !           594:        tf->tf_spc = (int)catcher;
        !           595:        tf->tf_r15 = (int)fp;
        !           596:        tf->tf_pr = (int)p->p_sigcode;
        !           597: }
        !           598:
        !           599: /*
        !           600:  * System call to cleanup state after a signal
        !           601:  * has been taken.  Reset signal mask and
        !           602:  * stack state from context left by sendsig (above).
        !           603:  * Return to previous pc and psl as specified by
        !           604:  * context left by sendsig. Check carefully to
        !           605:  * make sure that the user has not modified the
        !           606:  * psl to gain improper privileges or to cause
        !           607:  * a machine fault.
        !           608:  */
        !           609: int
        !           610: sys_sigreturn(struct proc *p, void *v, register_t *retval)
        !           611: {
        !           612:        struct sys_sigreturn_args /* {
        !           613:                syscallarg(struct sigcontext *) sigcntxp;
        !           614:        } */ *uap = v;
        !           615:        struct sigcontext *scp, context;
        !           616:        struct trapframe *tf;
        !           617:        int error;
        !           618:
        !           619:        /*
        !           620:         * The trampoline code hands us the context.
        !           621:         * It is unsafe to keep track of it ourselves, in the event that a
        !           622:         * program jumps out of a signal handler.
        !           623:         */
        !           624:        scp = SCARG(uap, sigcntxp);
        !           625:        if ((error = copyin((caddr_t)scp, &context, sizeof(*scp))) != 0)
        !           626:                return (error);
        !           627:
        !           628:        /* Restore signal context. */
        !           629:        tf = p->p_md.md_regs;
        !           630:
        !           631:        /* Check for security violations. */
        !           632:        if (((context.sc_reg.r_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0)
        !           633:                return (EINVAL);
        !           634:
        !           635:        tf->tf_spc = context.sc_reg.r_spc;
        !           636:        tf->tf_ssr = context.sc_reg.r_ssr;
        !           637:        tf->tf_macl = context.sc_reg.r_macl;
        !           638:        tf->tf_mach = context.sc_reg.r_mach;
        !           639:        tf->tf_pr = context.sc_reg.r_pr;
        !           640:        tf->tf_r13 = context.sc_reg.r_r13;
        !           641:        tf->tf_r12 = context.sc_reg.r_r12;
        !           642:        tf->tf_r11 = context.sc_reg.r_r11;
        !           643:        tf->tf_r10 = context.sc_reg.r_r10;
        !           644:        tf->tf_r9 = context.sc_reg.r_r9;
        !           645:        tf->tf_r8 = context.sc_reg.r_r8;
        !           646:        tf->tf_r7 = context.sc_reg.r_r7;
        !           647:        tf->tf_r6 = context.sc_reg.r_r6;
        !           648:        tf->tf_r5 = context.sc_reg.r_r5;
        !           649:        tf->tf_r4 = context.sc_reg.r_r4;
        !           650:        tf->tf_r3 = context.sc_reg.r_r3;
        !           651:        tf->tf_r2 = context.sc_reg.r_r2;
        !           652:        tf->tf_r1 = context.sc_reg.r_r1;
        !           653:        tf->tf_r0 = context.sc_reg.r_r0;
        !           654:        tf->tf_r15 = context.sc_reg.r_r15;
        !           655:        tf->tf_r14 = context.sc_reg.r_r14;
        !           656:
        !           657: #ifdef SH4
        !           658:        if (CPU_IS_SH4)
        !           659:                fpu_restore(&context.sc_fpreg);
        !           660: #endif
        !           661:
        !           662:        /* Restore signal stack. */
        !           663:        if (context.sc_onstack)
        !           664:                p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
        !           665:        else
        !           666:                p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
        !           667:        /* Restore signal mask. */
        !           668:        p->p_sigmask = context.sc_mask & ~sigcantmask;
        !           669:
        !           670:        return (EJUSTRETURN);
        !           671: }
        !           672:
        !           673: /*
        !           674:  * Clear registers on exec
        !           675:  */
        !           676: void
        !           677: setregs(struct proc *p, struct exec_package *pack, u_long stack,
        !           678:     register_t rval[2])
        !           679: {
        !           680:        struct trapframe *tf;
        !           681:        struct pcb *pcb = p->p_md.md_pcb;
        !           682:
        !           683:        p->p_md.md_flags &= ~MDP_USEDFPU;
        !           684:
        !           685:        tf = p->p_md.md_regs;
        !           686:
        !           687:        tf->tf_r0 = 0;
        !           688:        tf->tf_r1 = 0;
        !           689:        tf->tf_r2 = 0;
        !           690:        tf->tf_r3 = 0;
        !           691:        copyin((caddr_t)stack, &tf->tf_r4, sizeof(register_t)); /* argc */
        !           692:        tf->tf_r5 = stack + 4;                  /* argv */
        !           693:        tf->tf_r6 = stack + 4 * tf->tf_r4 + 8;  /* envp */
        !           694:        tf->tf_r7 = 0;
        !           695:        tf->tf_r8 = 0;
        !           696:        tf->tf_r9 = (int)PS_STRINGS;
        !           697:        tf->tf_r10 = 0;
        !           698:        tf->tf_r11 = 0;
        !           699:        tf->tf_r12 = 0;
        !           700:        tf->tf_r13 = 0;
        !           701:        tf->tf_r14 = 0;
        !           702:        tf->tf_spc = pack->ep_entry;
        !           703:        tf->tf_ssr = PSL_USERSET;
        !           704:        tf->tf_r15 = stack;
        !           705:
        !           706: #ifdef SH4
        !           707:        if (CPU_IS_SH4) {
        !           708:                /*
        !           709:                 * Clear floating point registers.
        !           710:                 */
        !           711:                bzero(&pcb->pcb_fp, sizeof(pcb->pcb_fp));
        !           712:                fpu_restore(&pcb->pcb_fp);
        !           713:        }
        !           714: #endif
        !           715:
        !           716:        rval[1] = 0;
        !           717: }
        !           718:
        !           719: void
        !           720: setrunqueue(struct proc *p)
        !           721: {
        !           722:        int whichq = p->p_priority / PPQ;
        !           723:        struct prochd *q;
        !           724:        struct proc *prev;
        !           725:
        !           726: #ifdef DIAGNOSTIC
        !           727:        if (p->p_back != NULL || p->p_wchan != NULL || p->p_stat != SRUN)
        !           728:                panic("setrunqueue");
        !           729: #endif
        !           730:        q = &qs[whichq];
        !           731:        prev = q->ph_rlink;
        !           732:        p->p_forw = (struct proc *)q;
        !           733:        q->ph_rlink = p;
        !           734:        prev->p_forw = p;
        !           735:        p->p_back = prev;
        !           736:        whichqs |= 1 << whichq;
        !           737: }
        !           738:
        !           739: void
        !           740: remrunqueue(struct proc *p)
        !           741: {
        !           742:        struct proc *prev, *next;
        !           743:        int whichq = p->p_priority / PPQ;
        !           744:
        !           745: #ifdef DIAGNOSTIC
        !           746:        if (((whichqs & (1 << whichq)) == 0))
        !           747:                panic("remrunqueue: bit %d not set", whichq);
        !           748: #endif
        !           749:        prev = p->p_back;
        !           750:        p->p_back = NULL;
        !           751:        next = p->p_forw;
        !           752:        prev->p_forw = next;
        !           753:        next->p_back = prev;
        !           754:        if (prev == next)
        !           755:                whichqs &= ~(1 << whichq);
        !           756: }
        !           757:
        !           758: /*
        !           759:  * Jump to reset vector.
        !           760:  */
        !           761: void
        !           762: cpu_reset()
        !           763: {
        !           764:        _cpu_exception_suspend();
        !           765:        _reg_write_4(SH_(EXPEVT), EXPEVT_RESET_MANUAL);
        !           766:
        !           767: #ifndef __lint__
        !           768:        goto *(void *)0xa0000000;
        !           769: #endif
        !           770:        /* NOTREACHED */
        !           771: }

CVSweb