[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.72.2.2

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

CVSweb <webmaster@jp.NetBSD.org>