[BACK]Return to sh3_machdep.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / sh3 / sh3

Annotation of src/sys/arch/sh3/sh3/sh3_machdep.c, Revision 1.69.6.3

1.69.6.1  mjf         1: /*     $NetBSD$        */
1.1       tsubai      2:
                      3: /*-
1.33      uch         4:  * Copyright (c) 1996, 1997, 1998, 2002 The NetBSD Foundation, Inc.
1.1       tsubai      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
                      9:  * Simulation Facility, NASA Ames Research Center.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     21:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     22:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     23:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     24:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     25:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     26:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     27:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     28:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     29:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     30:  * POSSIBILITY OF SUCH DAMAGE.
                     31:  */
                     32:
                     33: /*-
                     34:  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
                     35:  * All rights reserved.
                     36:  *
                     37:  * This code is derived from software contributed to Berkeley by
                     38:  * William Jolitz.
                     39:  *
                     40:  * Redistribution and use in source and binary forms, with or without
                     41:  * modification, are permitted provided that the following conditions
                     42:  * are met:
                     43:  * 1. Redistributions of source code must retain the above copyright
                     44:  *    notice, this list of conditions and the following disclaimer.
                     45:  * 2. Redistributions in binary form must reproduce the above copyright
                     46:  *    notice, this list of conditions and the following disclaimer in the
                     47:  *    documentation and/or other materials provided with the distribution.
1.51      agc        48:  * 3. Neither the name of the University nor the names of its contributors
1.1       tsubai     49:  *    may be used to endorse or promote products derived from this software
                     50:  *    without specific prior written permission.
                     51:  *
                     52:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     53:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     54:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     55:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     56:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     57:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     58:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     59:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     60:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     61:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     62:  * SUCH DAMAGE.
                     63:  *
                     64:  *     @(#)machdep.c   7.4 (Berkeley) 6/3/91
                     65:  */
1.49      lukem      66:
                     67: #include <sys/cdefs.h>
1.69.6.1  mjf        68: __KERNEL_RCSID(0, "$NetBSD$");
1.1       tsubai     69:
1.14      lukem      70: #include "opt_kgdb.h"
1.26      uch        71: #include "opt_memsize.h"
1.1       tsubai     72: #include "opt_compat_netbsd.h"
1.33      uch        73: #include "opt_kstack_debug.h"
1.1       tsubai     74:
                     75: #include <sys/param.h>
1.33      uch        76: #include <sys/systm.h>
                     77:
1.1       tsubai     78: #include <sys/buf.h>
                     79: #include <sys/exec.h>
                     80: #include <sys/kernel.h>
                     81: #include <sys/malloc.h>
                     82: #include <sys/mount.h>
1.33      uch        83: #include <sys/proc.h>
1.1       tsubai     84: #include <sys/signalvar.h>
1.48      nathanw    85: #include <sys/ras.h>
1.1       tsubai     86: #include <sys/syscallargs.h>
1.46      thorpej    87: #include <sys/ucontext.h>
1.1       tsubai     88: #include <sys/user.h>
                     89:
                     90: #ifdef KGDB
                     91: #include <sys/kgdb.h>
1.30      uch        92: #ifndef KGDB_DEVNAME
1.38      uch        93: #define        KGDB_DEVNAME "nodev"
1.1       tsubai     94: #endif
1.30      uch        95: const char kgdb_devname[] = KGDB_DEVNAME;
                     96: #endif /* KGDB */
1.7       mrg        97:
1.1       tsubai     98: #include <uvm/uvm_extern.h>
                     99:
1.22      uch       100: #include <sh3/cache.h>
1.25      uch       101: #include <sh3/clock.h>
1.36      uch       102: #include <sh3/exception.h>
1.33      uch       103: #include <sh3/locore.h>
1.36      uch       104: #include <sh3/mmu.h>
                    105: #include <sh3/intr.h>
1.22      uch       106:
1.38      uch       107: /* Our exported CPU info; we can have only one. */
1.34      uch       108: struct cpu_info cpu_info_store;
1.24      uch       109: int cpu_arch;
                    110: int cpu_product;
1.34      uch       111: char cpu_model[120];
1.1       tsubai    112:
1.33      uch       113: struct vm_map *mb_map;
                    114: struct vm_map *phys_map;
1.1       tsubai    115:
1.32      uch       116: int physmem;
1.33      uch       117: struct user *proc0paddr;       /* init_main.c use this. */
                    118: struct pcb *curpcb;
1.1       tsubai    119:
1.40      uch       120: #if !defined(IOM_RAM_BEGIN)
1.26      uch       121: #error "define IOM_RAM_BEGIN"
1.40      uch       122: #elif (IOM_RAM_BEGIN & SH3_P1SEG_BASE) != 0
                    123: #error "IOM_RAM_BEGIN is physical address. not P1 address."
1.26      uch       124: #endif
1.40      uch       125:
1.59      uwe       126: #define        VBR     (uint8_t *)SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN)
1.40      uch       127: vaddr_t ram_start = SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN);
1.26      uch       128: /* exception handler holder (sh3/sh3/exception_vector.S) */
                    129: extern char sh_vector_generic[], sh_vector_generic_end[];
                    130: extern char sh_vector_interrupt[], sh_vector_interrupt_end[];
1.37      uch       131: #ifdef SH3
1.33      uch       132: extern char sh3_vector_tlbmiss[], sh3_vector_tlbmiss_end[];
1.37      uch       133: #endif
                    134: #ifdef SH4
1.33      uch       135: extern char sh4_vector_tlbmiss[], sh4_vector_tlbmiss_end[];
1.37      uch       136: #endif
1.28      uch       137: /*
                    138:  * These variables are needed by /sbin/savecore
                    139:  */
1.59      uwe       140: uint32_t dumpmag = 0x8fca0101; /* magic number */
1.34      uch       141: int dumpsize;                  /* pages */
                    142: long dumplo;                   /* blocks */
1.28      uch       143:
1.67      uwe       144:
1.1       tsubai    145: void
1.24      uch       146: sh_cpu_init(int arch, int product)
                    147: {
                    148:        /* CPU type */
                    149:        cpu_arch = arch;
                    150:        cpu_product = product;
                    151:
1.27      uch       152: #if defined(SH3) && defined(SH4)
                    153:        /* Set register addresses */
                    154:        sh_devreg_init();
                    155: #endif
1.24      uch       156:        /* Cache access ops. */
                    157:        sh_cache_init();
                    158:
                    159:        /* MMU access ops. */
                    160:        sh_mmu_init();
1.25      uch       161:
                    162:        /* Hardclock, RTC initialize. */
                    163:        machine_clock_init();
1.26      uch       164:
1.36      uch       165:        /* ICU initiailze. */
1.69.6.1  mjf       166:        curcpu()->ci_idepth = -1;
1.36      uch       167:        intc_init();
                    168:
1.26      uch       169:        /* Exception vector. */
                    170:        memcpy(VBR + 0x100, sh_vector_generic,
                    171:            sh_vector_generic_end - sh_vector_generic);
1.37      uch       172: #ifdef SH3
1.33      uch       173:        if (CPU_IS_SH3)
                    174:                memcpy(VBR + 0x400, sh3_vector_tlbmiss,
                    175:                    sh3_vector_tlbmiss_end - sh3_vector_tlbmiss);
1.37      uch       176: #endif
                    177: #ifdef SH4
1.33      uch       178:        if (CPU_IS_SH4)
                    179:                memcpy(VBR + 0x400, sh4_vector_tlbmiss,
                    180:                    sh4_vector_tlbmiss_end - sh4_vector_tlbmiss);
1.37      uch       181: #endif
1.26      uch       182:        memcpy(VBR + 0x600, sh_vector_interrupt,
                    183:            sh_vector_interrupt_end - sh_vector_interrupt);
1.33      uch       184:
1.40      uch       185:        if (!SH_HAS_UNIFIED_CACHE)
                    186:                sh_icache_sync_all();
1.33      uch       187:
1.57      perry     188:        __asm volatile("ldc %0, vbr" :: "r"(VBR));
1.33      uch       189:
                    190:        /* kernel stack setup */
                    191:        __sh_switch_resume = CPU_IS_SH3 ? sh3_switch_resume : sh4_switch_resume;
1.40      uch       192:
                    193:        /* Set page size (4KB) */
                    194:        uvm_setpagesize();
1.24      uch       195: }
                    196:
1.67      uwe       197:
1.32      uch       198: /*
1.40      uch       199:  * void sh_proc0_init(void):
                    200:  *     Setup proc0 u-area.
1.32      uch       201:  */
1.40      uch       202: void
                    203: sh_proc0_init()
1.32      uch       204: {
1.40      uch       205:        struct switchframe *sf;
                    206:        vaddr_t u;
1.32      uch       207:
1.40      uch       208:        /* Steal process0 u-area */
                    209:        u = uvm_pageboot_alloc(USPACE);
                    210:        memset((void *)u, 0, USPACE);
1.32      uch       211:
                    212:        /* Setup proc0 */
1.40      uch       213:        proc0paddr = (struct user *)u;
1.46      thorpej   214:        lwp0.l_addr = proc0paddr;
1.38      uch       215:        /*
1.33      uch       216:         * u-area map:
1.47      thorpej   217:         * |user| .... | .................. |
                    218:         * | PAGE_SIZE | USPACE - PAGE_SIZE |
1.67      uwe       219:          *        frame bot        stack bot
1.40      uch       220:         * current frame ... r6_bank
1.67      uwe       221:         * stack bottom  ... r7_bank
1.40      uch       222:         * current stack ... r15
1.33      uch       223:         */
1.46      thorpej   224:        curpcb = lwp0.l_md.md_pcb = &lwp0.l_addr->u_pcb;
1.36      uch       225:
1.40      uch       226:        sf = &curpcb->pcb_sf;
1.65      uwe       227:
                    228: #ifdef KSTACK_DEBUG
                    229:        memset((char *)(u + sizeof(struct user)), 0x5a,
                    230:            PAGE_SIZE - sizeof(struct user));
                    231:        memset((char *)(u + PAGE_SIZE), 0xa5, USPACE - PAGE_SIZE);
                    232:        memset(sf, 0xb4, sizeof(struct switchframe));
                    233: #endif /* KSTACK_DEBUG */
                    234:
1.47      thorpej   235:        sf->sf_r6_bank = u + PAGE_SIZE;
1.64      uwe       236:        sf->sf_r7_bank = sf->sf_r15 = u + USPACE;
1.57      perry     237:        __asm volatile("ldc %0, r6_bank" :: "r"(sf->sf_r6_bank));
                    238:        __asm volatile("ldc %0, r7_bank" :: "r"(sf->sf_r7_bank));
1.33      uch       239:
1.46      thorpej   240:        lwp0.l_md.md_regs = (struct trapframe *)sf->sf_r6_bank - 1;
1.32      uch       241: }
                    242:
1.24      uch       243: void
1.34      uch       244: sh_startup()
1.1       tsubai    245: {
                    246:        vaddr_t minaddr, maxaddr;
                    247:        char pbuf[9];
1.22      uch       248:
1.55      lukem     249:        printf("%s%s", copyright, version);
1.36      uch       250:        if (*cpu_model != '\0')
                    251:                printf("%s", cpu_model);
1.33      uch       252: #ifdef DEBUG
                    253:        printf("general exception handler:\t%d byte\n",
1.40      uch       254:            sh_vector_generic_end - sh_vector_generic);
1.33      uch       255:        printf("TLB miss exception handler:\t%d byte\n",
1.37      uch       256: #if defined(SH3) && defined(SH4)
                    257:            CPU_IS_SH3 ? sh3_vector_tlbmiss_end - sh3_vector_tlbmiss :
                    258:            sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
                    259: #elif defined(SH3)
                    260:            sh3_vector_tlbmiss_end - sh3_vector_tlbmiss
                    261: #elif defined(SH4)
                    262:            sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
                    263: #endif
                    264:            );
1.33      uch       265:        printf("interrupt exception handler:\t%d byte\n",
1.40      uch       266:            sh_vector_interrupt_end - sh_vector_interrupt);
1.33      uch       267: #endif /* DEBUG */
1.1       tsubai    268:
                    269:        format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
                    270:        printf("total memory = %s\n", pbuf);
                    271:
1.54      pk        272:        minaddr = 0;
1.1       tsubai    273:
                    274:        /*
                    275:         * Allocate a submap for physio
                    276:         */
                    277:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
1.61      thorpej   278:            VM_PHYS_SIZE, 0, false, NULL);
1.1       tsubai    279:
                    280:        format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
                    281:        printf("avail memory = %s\n", pbuf);
                    282: }
                    283:
                    284: /*
1.28      uch       285:  * This is called by main to set dumplo and dumpsize.
                    286:  * Dumps always skip the first CLBYTES of disk space
                    287:  * in case there might be a disk label stored there.
                    288:  * If there is extra space, put dump at the end to
                    289:  * reduce the chance that swapping trashes it.
                    290:  */
                    291: void
                    292: cpu_dumpconf()
                    293: {
                    294: }
                    295:
                    296: void
                    297: dumpsys()
                    298: {
                    299: }
                    300:
                    301: /*
1.53      uwe       302:  * Get the base address of the signal frame either on the lwp's stack
                    303:  * or on the signal stack and set *onstack accordingly.  Caller then
                    304:  * just subtracts the size of appropriate struct sigframe_foo.
                    305:  */
                    306: static void *
                    307: getframe(struct lwp *l, int sig, int *onstack)
                    308: {
                    309:        struct proc *p = l->l_proc;
1.60      ad        310:        struct sigaltstack *sigstk= &l->l_sigstk;
1.53      uwe       311:
                    312:        /* Do we need to jump onto the signal stack? */
                    313:        *onstack = (sigstk->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0
                    314:                && (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
                    315:
                    316:        if (*onstack)
                    317:                return ((char *)sigstk->ss_sp + sigstk->ss_size);
                    318:        else
                    319:                return ((void *)l->l_md.md_regs->tf_r15);
                    320: }
                    321:
                    322: #ifdef COMPAT_16
                    323: /*
1.1       tsubai    324:  * Stack is set up to allow sigcode stored
                    325:  * in u. to call routine, followed by kcall
                    326:  * to sigreturn routine below.  After sigreturn
                    327:  * resets the signal mask, the stack, and the
                    328:  * frame pointer, it returns to the user
                    329:  * specified pc, psl.
                    330:  */
1.53      uwe       331: static void
                    332: sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask)
1.1       tsubai    333: {
1.46      thorpej   334:        struct lwp *l = curlwp;
                    335:        struct proc *p = l->l_proc;
1.44      thorpej   336:        struct sigacts *ps = p->p_sigacts;
1.53      uwe       337:        struct trapframe *tf = l->l_md.md_regs;
                    338:        int sig = ksi->ksi_info._signo;
                    339:        sig_t catcher = SIGACTION(p, sig).sa_handler;
                    340:        struct sigframe_sigcontext *fp, frame;
1.60      ad        341:        int onstack, error;
1.1       tsubai    342:
1.53      uwe       343:        fp = getframe(l, sig, &onstack);
                    344:        --fp;
1.1       tsubai    345:
                    346:        /* Save register context. */
                    347:        frame.sf_sc.sc_ssr = tf->tf_ssr;
                    348:        frame.sf_sc.sc_spc = tf->tf_spc;
                    349:        frame.sf_sc.sc_pr = tf->tf_pr;
                    350:        frame.sf_sc.sc_r15 = tf->tf_r15;
                    351:        frame.sf_sc.sc_r14 = tf->tf_r14;
                    352:        frame.sf_sc.sc_r13 = tf->tf_r13;
                    353:        frame.sf_sc.sc_r12 = tf->tf_r12;
                    354:        frame.sf_sc.sc_r11 = tf->tf_r11;
                    355:        frame.sf_sc.sc_r10 = tf->tf_r10;
                    356:        frame.sf_sc.sc_r9 = tf->tf_r9;
                    357:        frame.sf_sc.sc_r8 = tf->tf_r8;
                    358:        frame.sf_sc.sc_r7 = tf->tf_r7;
                    359:        frame.sf_sc.sc_r6 = tf->tf_r6;
                    360:        frame.sf_sc.sc_r5 = tf->tf_r5;
                    361:        frame.sf_sc.sc_r4 = tf->tf_r4;
                    362:        frame.sf_sc.sc_r3 = tf->tf_r3;
                    363:        frame.sf_sc.sc_r2 = tf->tf_r2;
                    364:        frame.sf_sc.sc_r1 = tf->tf_r1;
                    365:        frame.sf_sc.sc_r0 = tf->tf_r0;
1.40      uch       366:        frame.sf_sc.sc_expevt = tf->tf_expevt;
1.1       tsubai    367:
                    368:        /* Save signal stack. */
1.60      ad        369:        frame.sf_sc.sc_onstack = l->l_sigstk.ss_flags & SS_ONSTACK;
1.1       tsubai    370:
                    371:        /* Save signal mask. */
                    372:        frame.sf_sc.sc_mask = *mask;
                    373:
1.60      ad        374:        sendsig_reset(l, sig);
                    375:
1.69.6.2  mjf       376:        mutex_exit(p->p_lock);
1.60      ad        377:        error = copyout(&frame, fp, sizeof(frame));
1.69.6.2  mjf       378:        mutex_enter(p->p_lock);
1.60      ad        379:
                    380:        if (error != 0) {
1.1       tsubai    381:                /*
                    382:                 * Process has trashed its stack; give it an illegal
                    383:                 * instruction to halt it in its tracks.
                    384:                 */
1.46      thorpej   385:                sigexit(l, SIGILL);
1.1       tsubai    386:                /* NOTREACHED */
                    387:        }
                    388:
                    389:        /*
1.43      thorpej   390:         * Build context to run handler in.  We invoke the handler
                    391:         * directly, only returning via the trampoline.
1.1       tsubai    392:         */
1.44      thorpej   393:        switch (ps->sa_sigdesc[sig].sd_vers) {
                    394:        case 0:         /* legacy on-stack sigtramp */
                    395:                tf->tf_pr = (int)p->p_sigctx.ps_sigcode;
                    396:                break;
                    397:
                    398:        case 1:
                    399:                tf->tf_pr = (int)ps->sa_sigdesc[sig].sd_tramp;
                    400:                break;
                    401:
                    402:        default:
                    403:                /* Don't know what trampoline version; kill it. */
1.53      uwe       404:                printf("sendsig_sigcontext: bad version %d\n",
                    405:                       ps->sa_sigdesc[sig].sd_vers);
1.46      thorpej   406:                sigexit(l, SIGILL);
1.44      thorpej   407:        }
                    408:
1.42      thorpej   409:        tf->tf_r4 = sig;
1.53      uwe       410:        tf->tf_r5 = ksi->ksi_code;
1.42      thorpej   411:        tf->tf_r6 = (int)&fp->sf_sc;
1.53      uwe       412:        tf->tf_spc = (int)catcher;
1.1       tsubai    413:        tf->tf_r15 = (int)fp;
                    414:
1.53      uwe       415:        /* Remember if we're now on the signal stack. */
                    416:        if (onstack)
1.60      ad        417:                l->l_sigstk.ss_flags |= SS_ONSTACK;
1.53      uwe       418: }
                    419: #endif /* COMPAT_16 */
                    420:
                    421: static void
                    422: sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
                    423: {
                    424:        struct lwp *l = curlwp;
                    425:        struct proc *p = l->l_proc;
                    426:        struct sigacts *ps = p->p_sigacts;
                    427:        struct trapframe *tf = l->l_md.md_regs;
1.60      ad        428:        int sig = ksi->ksi_signo, error;
1.53      uwe       429:        sig_t catcher = SIGACTION(p, sig).sa_handler;
                    430:        struct sigframe_siginfo *fp, frame;
                    431:        int onstack;
                    432:
                    433:        switch (ps->sa_sigdesc[sig].sd_vers) {
1.58      uwe       434:        case 0:         /* FALLTHROUGH */ /* handled by sendsig_sigcontext */
                    435:        case 1:         /* FALLTHROUGH */ /* handled by sendsig_sigcontext */
1.53      uwe       436:        default:        /* unknown version */
                    437:                printf("sendsig_siginfo: bad version %d\n",
                    438:                       ps->sa_sigdesc[sig].sd_vers);
                    439:                sigexit(l, SIGILL);
1.58      uwe       440:                /* NOTREACHED */
1.53      uwe       441:        case 2:
                    442:                break;
                    443:        }
                    444:
                    445:        fp = getframe(l, sig, &onstack);
                    446:        --fp;
                    447:
                    448:        frame.sf_si._info = ksi->ksi_info;
1.63      pooka     449:        frame.sf_uc.uc_link = l->l_ctxlink;
1.53      uwe       450:        frame.sf_uc.uc_sigmask = *mask;
                    451:        frame.sf_uc.uc_flags = _UC_SIGMASK;
1.60      ad        452:        frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK)
1.53      uwe       453:                ? _UC_SETSTACK : _UC_CLRSTACK;
                    454:        memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack));
1.60      ad        455:        sendsig_reset(l, sig);
1.69.6.2  mjf       456:        mutex_exit(p->p_lock);
1.53      uwe       457:        cpu_getmcontext(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags);
1.60      ad        458:        error = copyout(&frame, fp, sizeof(frame));
1.69.6.2  mjf       459:        mutex_enter(p->p_lock);
1.53      uwe       460:
1.60      ad        461:        if (error != 0) {
1.53      uwe       462:                /*
                    463:                 * Process has trashed its stack; give it an illegal
                    464:                 * instruction to halt it in its tracks.
                    465:                 */
                    466:                sigexit(l, SIGILL);
                    467:                /* NOTREACHED */
                    468:        }
                    469:
                    470:        tf->tf_r4 = sig;                /* "signum" argument for handler */
                    471:        tf->tf_r5 = (int)&fp->sf_si;    /* "sip" argument for handler */
                    472:        tf->tf_r6 = (int)&fp->sf_uc;    /* "ucp" argument for handler */
                    473:        tf->tf_spc = (int)catcher;
                    474:        tf->tf_r15 = (int)fp;
                    475:        tf->tf_pr = (int)ps->sa_sigdesc[sig].sd_tramp;
                    476:
                    477:        /* Remember if we're now on the signal stack. */
1.1       tsubai    478:        if (onstack)
1.60      ad        479:                l->l_sigstk.ss_flags |= SS_ONSTACK;
1.1       tsubai    480: }
                    481:
                    482: /*
1.53      uwe       483:  * Send an interrupt to process.
                    484:  */
                    485: void
                    486: sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
                    487: {
                    488: #ifdef COMPAT_16
                    489:        if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2)
                    490:                sendsig_sigcontext(ksi, mask);
                    491:        else
                    492: #endif
                    493:                sendsig_siginfo(ksi, mask);
                    494: }
                    495:
                    496: #ifdef COMPAT_16
                    497: /*
1.1       tsubai    498:  * System call to cleanup state after a signal
                    499:  * has been taken.  Reset signal mask and
                    500:  * stack state from context left by sendsig (above).
                    501:  * Return to previous pc and psl as specified by
                    502:  * context left by sendsig. Check carefully to
                    503:  * make sure that the user has not modified the
                    504:  * psl to gain improper privileges or to cause
                    505:  * a machine fault.
                    506:  */
                    507: int
1.68      dsl       508: compat_16_sys___sigreturn14(struct lwp *l, const struct compat_16_sys___sigreturn14_args *uap, register_t *retval)
1.1       tsubai    509: {
1.68      dsl       510:        /* {
1.1       tsubai    511:                syscallarg(struct sigcontext *) sigcntxp;
1.68      dsl       512:        } */
1.1       tsubai    513:        struct sigcontext *scp, context;
                    514:        struct trapframe *tf;
1.46      thorpej   515:        struct proc *p = l->l_proc;
1.1       tsubai    516:
                    517:        /*
                    518:         * The trampoline code hands us the context.
                    519:         * It is unsafe to keep track of it ourselves, in the event that a
                    520:         * program jumps out of a signal handler.
                    521:         */
                    522:        scp = SCARG(uap, sigcntxp);
1.62      christos  523:        if (copyin((void *)scp, &context, sizeof(*scp)) != 0)
1.1       tsubai    524:                return (EFAULT);
                    525:
                    526:        /* Restore signal context. */
1.46      thorpej   527:        tf = l->l_md.md_regs;
1.1       tsubai    528:
1.13      msaitoh   529:        /* Check for security violations. */
                    530:        if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0)
                    531:                return (EINVAL);
                    532:
                    533:        tf->tf_ssr = context.sc_ssr;
                    534:
1.1       tsubai    535:        tf->tf_r0 = context.sc_r0;
                    536:        tf->tf_r1 = context.sc_r1;
                    537:        tf->tf_r2 = context.sc_r2;
                    538:        tf->tf_r3 = context.sc_r3;
                    539:        tf->tf_r4 = context.sc_r4;
                    540:        tf->tf_r5 = context.sc_r5;
                    541:        tf->tf_r6 = context.sc_r6;
                    542:        tf->tf_r7 = context.sc_r7;
                    543:        tf->tf_r8 = context.sc_r8;
                    544:        tf->tf_r9 = context.sc_r9;
                    545:        tf->tf_r10 = context.sc_r10;
                    546:        tf->tf_r11 = context.sc_r11;
                    547:        tf->tf_r12 = context.sc_r12;
                    548:        tf->tf_r13 = context.sc_r13;
                    549:        tf->tf_r14 = context.sc_r14;
                    550:        tf->tf_spc = context.sc_spc;
                    551:        tf->tf_r15 = context.sc_r15;
                    552:        tf->tf_pr = context.sc_pr;
                    553:
1.69.6.2  mjf       554:        mutex_enter(p->p_lock);
1.1       tsubai    555:        /* Restore signal stack. */
                    556:        if (context.sc_onstack & SS_ONSTACK)
1.60      ad        557:                l->l_sigstk.ss_flags |= SS_ONSTACK;
1.1       tsubai    558:        else
1.60      ad        559:                l->l_sigstk.ss_flags &= ~SS_ONSTACK;
1.1       tsubai    560:        /* Restore signal mask. */
1.60      ad        561:        (void) sigprocmask1(l, SIG_SETMASK, &context.sc_mask, 0);
1.69.6.2  mjf       562:        mutex_exit(p->p_lock);
1.1       tsubai    563:
                    564:        return (EJUSTRETURN);
                    565: }
1.53      uwe       566: #endif /* COMPAT_16 */
1.1       tsubai    567:
1.46      thorpej   568: void
                    569: cpu_getmcontext(l, mcp, flags)
                    570:        struct lwp *l;
                    571:        mcontext_t *mcp;
                    572:        unsigned int *flags;
                    573: {
                    574:        const struct trapframe *tf = l->l_md.md_regs;
                    575:        __greg_t *gr = mcp->__gregs;
1.48      nathanw   576:        __greg_t ras_pc;
1.46      thorpej   577:
                    578:        /* Save register context. */
1.69.6.2  mjf       579:        gr[_REG_GBR]    = tf->tf_gbr;
1.46      thorpej   580:        gr[_REG_PC]     = tf->tf_spc;
                    581:        gr[_REG_SR]     = tf->tf_ssr;
                    582:        gr[_REG_MACL]   = tf->tf_macl;
                    583:        gr[_REG_MACH]   = tf->tf_mach;
                    584:        gr[_REG_PR]     = tf->tf_pr;
                    585:        gr[_REG_R14]    = tf->tf_r14;
                    586:        gr[_REG_R13]    = tf->tf_r13;
                    587:        gr[_REG_R12]    = tf->tf_r12;
                    588:        gr[_REG_R11]    = tf->tf_r11;
                    589:        gr[_REG_R10]    = tf->tf_r10;
                    590:        gr[_REG_R9]     = tf->tf_r9;
                    591:        gr[_REG_R8]     = tf->tf_r8;
                    592:        gr[_REG_R7]     = tf->tf_r7;
                    593:        gr[_REG_R6]     = tf->tf_r6;
                    594:        gr[_REG_R5]     = tf->tf_r5;
                    595:        gr[_REG_R4]     = tf->tf_r4;
                    596:        gr[_REG_R3]     = tf->tf_r3;
                    597:        gr[_REG_R2]     = tf->tf_r2;
                    598:        gr[_REG_R1]     = tf->tf_r1;
                    599:        gr[_REG_R0]     = tf->tf_r0;
                    600:        gr[_REG_R15]    = tf->tf_r15;
1.48      nathanw   601:
                    602:        if ((ras_pc = (__greg_t)ras_lookup(l->l_proc,
1.62      christos  603:            (void *) gr[_REG_PC])) != -1)
1.48      nathanw   604:                gr[_REG_PC] = ras_pc;
                    605:
1.46      thorpej   606:        *flags |= _UC_CPU;
                    607:
                    608:        /* FPU context is currently not handled by the kernel. */
                    609:        memset(&mcp->__fpregs, 0, sizeof (mcp->__fpregs));
                    610: }
                    611:
                    612: int
                    613: cpu_setmcontext(l, mcp, flags)
                    614:        struct lwp *l;
                    615:        const mcontext_t *mcp;
                    616:        unsigned int flags;
                    617: {
                    618:        struct trapframe *tf = l->l_md.md_regs;
                    619:        const __greg_t *gr = mcp->__gregs;
1.60      ad        620:        struct proc *p = l->l_proc;
1.46      thorpej   621:
                    622:        /* Restore register context, if any. */
                    623:        if ((flags & _UC_CPU) != 0) {
                    624:                /* Check for security violations. */
                    625:                if (((tf->tf_ssr ^ gr[_REG_SR]) & PSL_USERSTATIC) != 0)
                    626:                        return (EINVAL);
1.64      uwe       627:
1.69.6.2  mjf       628:                tf->tf_gbr    = gr[_REG_GBR];
1.46      thorpej   629:                tf->tf_spc    = gr[_REG_PC];
                    630:                tf->tf_ssr    = gr[_REG_SR];
                    631:                tf->tf_macl   = gr[_REG_MACL];
                    632:                tf->tf_mach   = gr[_REG_MACH];
                    633:                tf->tf_pr     = gr[_REG_PR];
                    634:                tf->tf_r14    = gr[_REG_R14];
                    635:                tf->tf_r13    = gr[_REG_R13];
                    636:                tf->tf_r12    = gr[_REG_R12];
                    637:                tf->tf_r11    = gr[_REG_R11];
                    638:                tf->tf_r10    = gr[_REG_R10];
                    639:                tf->tf_r9     = gr[_REG_R9];
                    640:                tf->tf_r8     = gr[_REG_R8];
                    641:                tf->tf_r7     = gr[_REG_R7];
                    642:                tf->tf_r6     = gr[_REG_R6];
                    643:                tf->tf_r5     = gr[_REG_R5];
                    644:                tf->tf_r4     = gr[_REG_R4];
                    645:                tf->tf_r3     = gr[_REG_R3];
                    646:                tf->tf_r2     = gr[_REG_R2];
                    647:                tf->tf_r1     = gr[_REG_R1];
                    648:                tf->tf_r0     = gr[_REG_R0];
                    649:                tf->tf_r15    = gr[_REG_R15];
                    650:        }
1.53      uwe       651:
                    652: #if 0
                    653:        /* XXX: FPU context is currently not handled by the kernel. */
                    654:        if (flags & _UC_FPU) {
                    655:                /* TODO */;
                    656:        }
                    657: #endif
                    658:
1.69.6.2  mjf       659:        mutex_enter(p->p_lock);
1.53      uwe       660:        if (flags & _UC_SETSTACK)
1.60      ad        661:                l->l_sigstk.ss_flags |= SS_ONSTACK;
1.53      uwe       662:        if (flags & _UC_CLRSTACK)
1.60      ad        663:                l->l_sigstk.ss_flags &= ~SS_ONSTACK;
1.69.6.2  mjf       664:        mutex_exit(p->p_lock);
1.46      thorpej   665:
                    666:        return (0);
                    667: }
                    668:
1.1       tsubai    669: /*
                    670:  * Clear registers on exec
                    671:  */
                    672: void
1.46      thorpej   673: setregs(struct lwp *l, struct exec_package *pack, u_long stack)
1.1       tsubai    674: {
1.40      uch       675:        struct trapframe *tf;
1.1       tsubai    676:
1.46      thorpej   677:        l->l_md.md_flags &= ~MDP_USEDFPU;
1.1       tsubai    678:
1.46      thorpej   679:        tf = l->l_md.md_regs;
1.1       tsubai    680:
1.69.6.2  mjf       681:        tf->tf_ssr = PSL_USERSET;
                    682:        tf->tf_spc = pack->ep_entry;
                    683:        tf->tf_pr = 0;
                    684:
                    685:        tf->tf_gbr = 0;
                    686:        tf->tf_macl = 0;
                    687:        tf->tf_mach = 0;
                    688:
1.1       tsubai    689:        tf->tf_r0 = 0;
                    690:        tf->tf_r1 = 0;
                    691:        tf->tf_r2 = 0;
                    692:        tf->tf_r3 = 0;
1.62      christos  693:        tf->tf_r4 = fuword((void *)stack);      /* argc */
1.40      uch       694:        tf->tf_r5 = stack + 4;                  /* argv */
                    695:        tf->tf_r6 = stack + 4 * tf->tf_r4 + 8;  /* envp */
1.1       tsubai    696:        tf->tf_r7 = 0;
                    697:        tf->tf_r8 = 0;
1.46      thorpej   698:        tf->tf_r9 = (int)l->l_proc->p_psstr;
1.1       tsubai    699:        tf->tf_r10 = 0;
                    700:        tf->tf_r11 = 0;
                    701:        tf->tf_r12 = 0;
                    702:        tf->tf_r13 = 0;
                    703:        tf->tf_r14 = 0;
                    704:        tf->tf_r15 = stack;
1.28      uch       705: }
                    706:
                    707: /*
                    708:  * Jump to reset vector.
                    709:  */
                    710: void
                    711: cpu_reset()
                    712: {
                    713:
                    714:        _cpu_exception_suspend();
1.40      uch       715:        _reg_write_4(SH_(EXPEVT), EXPEVT_RESET_MANUAL);
1.28      uch       716:
1.58      uwe       717: #ifndef __lint__
                    718:        goto *(void *)0xa0000000;
                    719: #endif
1.29      uch       720:        /* NOTREACHED */
1.1       tsubai    721: }

CVSweb <webmaster@jp.NetBSD.org>