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

1.96.2.1! yamt        1: /*     $NetBSD: sh3_machdep.c,v 1.96 2011/07/25 21:12:23 dyoung 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.96.2.1! yamt       68: __KERNEL_RCSID(0, "$NetBSD: sh3_machdep.c,v 1.96 2011/07/25 21:12:23 dyoung Exp $");
1.1       tsubai     69:
1.90      uwe        70: #include "opt_ddb.h"
1.14      lukem      71: #include "opt_kgdb.h"
1.26      uch        72: #include "opt_memsize.h"
1.33      uch        73: #include "opt_kstack_debug.h"
1.90      uwe        74: #include "opt_ptrace.h"
1.1       tsubai     75:
                     76: #include <sys/param.h>
1.33      uch        77: #include <sys/systm.h>
                     78:
1.1       tsubai     79: #include <sys/buf.h>
                     80: #include <sys/exec.h>
                     81: #include <sys/kernel.h>
                     82: #include <sys/malloc.h>
                     83: #include <sys/mount.h>
1.33      uch        84: #include <sys/proc.h>
1.1       tsubai     85: #include <sys/signalvar.h>
1.48      nathanw    86: #include <sys/ras.h>
1.1       tsubai     87: #include <sys/syscallargs.h>
1.46      thorpej    88: #include <sys/ucontext.h>
1.91      joerg      89: #include <sys/cpu.h>
1.94      dyoung     90: #include <sys/bus.h>
1.1       tsubai     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.87      uebayasi  100: #include <uvm/uvm.h>
1.1       tsubai    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>
1.88      rmind     107: #include <sh3/pcb.h>
1.36      uch       108: #include <sh3/intr.h>
1.90      uwe       109: #include <sh3/ubcreg.h>
1.22      uch       110:
1.38      uch       111: /* Our exported CPU info; we can have only one. */
1.34      uch       112: struct cpu_info cpu_info_store;
1.24      uch       113: int cpu_arch;
                    114: int cpu_product;
1.34      uch       115: char cpu_model[120];
1.1       tsubai    116:
1.33      uch       117: struct vm_map *phys_map;
1.1       tsubai    118:
1.33      uch       119: struct pcb *curpcb;
1.1       tsubai    120:
1.40      uch       121: #if !defined(IOM_RAM_BEGIN)
1.26      uch       122: #error "define IOM_RAM_BEGIN"
1.40      uch       123: #elif (IOM_RAM_BEGIN & SH3_P1SEG_BASE) != 0
                    124: #error "IOM_RAM_BEGIN is physical address. not P1 address."
1.26      uch       125: #endif
1.40      uch       126:
1.59      uwe       127: #define        VBR     (uint8_t *)SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN)
1.40      uch       128: vaddr_t ram_start = SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN);
1.26      uch       129: /* exception handler holder (sh3/sh3/exception_vector.S) */
                    130: extern char sh_vector_generic[], sh_vector_generic_end[];
                    131: extern char sh_vector_interrupt[], sh_vector_interrupt_end[];
1.37      uch       132: #ifdef SH3
1.33      uch       133: extern char sh3_vector_tlbmiss[], sh3_vector_tlbmiss_end[];
1.37      uch       134: #endif
                    135: #ifdef SH4
1.33      uch       136: extern char sh4_vector_tlbmiss[], sh4_vector_tlbmiss_end[];
1.37      uch       137: #endif
1.28      uch       138: /*
                    139:  * These variables are needed by /sbin/savecore
                    140:  */
1.59      uwe       141: uint32_t dumpmag = 0x8fca0101; /* magic number */
1.34      uch       142: int dumpsize;                  /* pages */
                    143: long dumplo;                   /* blocks */
1.28      uch       144:
1.67      uwe       145:
1.1       tsubai    146: void
1.24      uch       147: sh_cpu_init(int arch, int product)
                    148: {
                    149:        /* CPU type */
                    150:        cpu_arch = arch;
                    151:        cpu_product = product;
                    152:
1.27      uch       153: #if defined(SH3) && defined(SH4)
                    154:        /* Set register addresses */
                    155:        sh_devreg_init();
                    156: #endif
1.24      uch       157:        /* Cache access ops. */
                    158:        sh_cache_init();
                    159:
                    160:        /* MMU access ops. */
                    161:        sh_mmu_init();
1.25      uch       162:
                    163:        /* Hardclock, RTC initialize. */
                    164:        machine_clock_init();
1.26      uch       165:
1.36      uch       166:        /* ICU initiailze. */
1.70      uwe       167:        curcpu()->ci_idepth = -1;
1.36      uch       168:        intc_init();
                    169:
1.26      uch       170:        /* Exception vector. */
                    171:        memcpy(VBR + 0x100, sh_vector_generic,
                    172:            sh_vector_generic_end - sh_vector_generic);
1.37      uch       173: #ifdef SH3
1.33      uch       174:        if (CPU_IS_SH3)
                    175:                memcpy(VBR + 0x400, sh3_vector_tlbmiss,
                    176:                    sh3_vector_tlbmiss_end - sh3_vector_tlbmiss);
1.37      uch       177: #endif
                    178: #ifdef SH4
1.33      uch       179:        if (CPU_IS_SH4)
                    180:                memcpy(VBR + 0x400, sh4_vector_tlbmiss,
                    181:                    sh4_vector_tlbmiss_end - sh4_vector_tlbmiss);
1.37      uch       182: #endif
1.26      uch       183:        memcpy(VBR + 0x600, sh_vector_interrupt,
                    184:            sh_vector_interrupt_end - sh_vector_interrupt);
1.33      uch       185:
1.40      uch       186:        if (!SH_HAS_UNIFIED_CACHE)
                    187:                sh_icache_sync_all();
1.33      uch       188:
1.57      perry     189:        __asm volatile("ldc %0, vbr" :: "r"(VBR));
1.33      uch       190:
                    191:        /* kernel stack setup */
                    192:        __sh_switch_resume = CPU_IS_SH3 ? sh3_switch_resume : sh4_switch_resume;
1.40      uch       193:
                    194:        /* Set page size (4KB) */
                    195:        uvm_setpagesize();
1.90      uwe       196:
                    197:        /* setup UBC channel A for single-stepping */
                    198: #if defined(PTRACE) || defined(DDB)
                    199:        _reg_write_2(SH_(BBRA), 0); /* disable channel A */
                    200:        _reg_write_2(SH_(BBRB), 0); /* disable channel B */
                    201:
                    202: #ifdef SH3
                    203:        if (CPU_IS_SH3) {
                    204:                /* A: break after execution, ignore ASID */
                    205:                _reg_write_4(SH3_BRCR, (UBC_CTL_A_AFTER_INSN
                    206:                                        | SH3_UBC_CTL_A_MASK_ASID));
                    207:
                    208:                /* A: compare all address bits */
                    209:                _reg_write_4(SH3_BAMRA, 0x00000000);
                    210:        }
                    211: #endif /* SH3 */
                    212:
                    213: #ifdef SH4
                    214:        if (CPU_IS_SH4) {
                    215:                /* A: break after execution */
                    216:                _reg_write_2(SH4_BRCR, UBC_CTL_A_AFTER_INSN);
                    217:
                    218:                /* A: compare all address bits, ignore ASID */
                    219:                _reg_write_1(SH4_BAMRA, SH4_UBC_MASK_NONE | SH4_UBC_MASK_ASID);
                    220:        }
                    221: #endif /* SH4 */
                    222: #endif
1.24      uch       223: }
                    224:
1.67      uwe       225:
1.32      uch       226: /*
1.40      uch       227:  * void sh_proc0_init(void):
                    228:  *     Setup proc0 u-area.
1.32      uch       229:  */
1.40      uch       230: void
1.96.2.1! yamt      231: sh_proc0_init(void)
1.32      uch       232: {
1.40      uch       233:        struct switchframe *sf;
                    234:        vaddr_t u;
1.32      uch       235:
1.40      uch       236:        /* Steal process0 u-area */
                    237:        u = uvm_pageboot_alloc(USPACE);
                    238:        memset((void *)u, 0, USPACE);
1.32      uch       239:
1.84      rmind     240:        /* Setup uarea for lwp0 */
                    241:        uvm_lwp_setuarea(&lwp0, u);
1.83      matt      242:
1.38      uch       243:        /*
1.33      uch       244:         * u-area map:
1.84      rmind     245:         * |pcb| .... | .................. |
1.47      thorpej   246:         * | PAGE_SIZE | USPACE - PAGE_SIZE |
1.67      uwe       247:          *        frame bot        stack bot
1.40      uch       248:         * current frame ... r6_bank
1.67      uwe       249:         * stack bottom  ... r7_bank
1.40      uch       250:         * current stack ... r15
1.33      uch       251:         */
1.82      rmind     252:        curpcb = lwp_getpcb(&lwp0);
                    253:        lwp0.l_md.md_pcb = curpcb;
1.36      uch       254:
1.40      uch       255:        sf = &curpcb->pcb_sf;
1.65      uwe       256:
                    257: #ifdef KSTACK_DEBUG
1.82      rmind     258:        memset((char *)(u + sizeof(struct pcb)), 0x5a,
                    259:            PAGE_SIZE - sizeof(struct pcb));
1.65      uwe       260:        memset((char *)(u + PAGE_SIZE), 0xa5, USPACE - PAGE_SIZE);
                    261:        memset(sf, 0xb4, sizeof(struct switchframe));
                    262: #endif /* KSTACK_DEBUG */
                    263:
1.47      thorpej   264:        sf->sf_r6_bank = u + PAGE_SIZE;
1.64      uwe       265:        sf->sf_r7_bank = sf->sf_r15 = u + USPACE;
1.57      perry     266:        __asm volatile("ldc %0, r6_bank" :: "r"(sf->sf_r6_bank));
                    267:        __asm volatile("ldc %0, r7_bank" :: "r"(sf->sf_r7_bank));
1.33      uch       268:
1.46      thorpej   269:        lwp0.l_md.md_regs = (struct trapframe *)sf->sf_r6_bank - 1;
1.32      uch       270: }
                    271:
1.24      uch       272: void
1.80      cegger    273: sh_startup(void)
1.1       tsubai    274: {
                    275:        vaddr_t minaddr, maxaddr;
                    276:        char pbuf[9];
1.22      uch       277:
1.55      lukem     278:        printf("%s%s", copyright, version);
1.36      uch       279:        if (*cpu_model != '\0')
                    280:                printf("%s", cpu_model);
1.33      uch       281: #ifdef DEBUG
                    282:        printf("general exception handler:\t%d byte\n",
1.40      uch       283:            sh_vector_generic_end - sh_vector_generic);
1.33      uch       284:        printf("TLB miss exception handler:\t%d byte\n",
1.37      uch       285: #if defined(SH3) && defined(SH4)
                    286:            CPU_IS_SH3 ? sh3_vector_tlbmiss_end - sh3_vector_tlbmiss :
                    287:            sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
                    288: #elif defined(SH3)
                    289:            sh3_vector_tlbmiss_end - sh3_vector_tlbmiss
                    290: #elif defined(SH4)
                    291:            sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
                    292: #endif
                    293:            );
1.33      uch       294:        printf("interrupt exception handler:\t%d byte\n",
1.40      uch       295:            sh_vector_interrupt_end - sh_vector_interrupt);
1.33      uch       296: #endif /* DEBUG */
1.1       tsubai    297:
                    298:        format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
                    299:        printf("total memory = %s\n", pbuf);
                    300:
1.54      pk        301:        minaddr = 0;
1.1       tsubai    302:
                    303:        /*
                    304:         * Allocate a submap for physio
                    305:         */
                    306:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
1.61      thorpej   307:            VM_PHYS_SIZE, 0, false, NULL);
1.1       tsubai    308:
                    309:        format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
                    310:        printf("avail memory = %s\n", pbuf);
                    311: }
                    312:
                    313: /*
1.28      uch       314:  * This is called by main to set dumplo and dumpsize.
                    315:  * Dumps always skip the first CLBYTES of disk space
                    316:  * in case there might be a disk label stored there.
                    317:  * If there is extra space, put dump at the end to
                    318:  * reduce the chance that swapping trashes it.
                    319:  */
                    320: void
1.80      cegger    321: cpu_dumpconf(void)
1.28      uch       322: {
                    323: }
                    324:
                    325: void
1.80      cegger    326: dumpsys(void)
1.28      uch       327: {
                    328: }
                    329:
                    330: /*
1.53      uwe       331:  * Get the base address of the signal frame either on the lwp's stack
                    332:  * or on the signal stack and set *onstack accordingly.  Caller then
                    333:  * just subtracts the size of appropriate struct sigframe_foo.
                    334:  */
1.78      uwe       335: void *
                    336: getframe(const struct lwp *l, int sig, int *onstack)
1.53      uwe       337: {
1.78      uwe       338:        const struct proc *p = l->l_proc;
                    339:        const struct sigaltstack *sigstk= &l->l_sigstk;
1.53      uwe       340:
                    341:        /* Do we need to jump onto the signal stack? */
                    342:        *onstack = (sigstk->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0
                    343:                && (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
                    344:
                    345:        if (*onstack)
                    346:                return ((char *)sigstk->ss_sp + sigstk->ss_size);
                    347:        else
                    348:                return ((void *)l->l_md.md_regs->tf_r15);
                    349: }
                    350:
1.77      ad        351: void
1.53      uwe       352: sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
                    353: {
                    354:        struct lwp *l = curlwp;
                    355:        struct proc *p = l->l_proc;
                    356:        struct sigacts *ps = p->p_sigacts;
                    357:        struct trapframe *tf = l->l_md.md_regs;
1.60      ad        358:        int sig = ksi->ksi_signo, error;
1.53      uwe       359:        sig_t catcher = SIGACTION(p, sig).sa_handler;
                    360:        struct sigframe_siginfo *fp, frame;
                    361:        int onstack;
                    362:
                    363:        fp = getframe(l, sig, &onstack);
                    364:        --fp;
                    365:
                    366:        frame.sf_si._info = ksi->ksi_info;
1.63      pooka     367:        frame.sf_uc.uc_link = l->l_ctxlink;
1.53      uwe       368:        frame.sf_uc.uc_sigmask = *mask;
                    369:        frame.sf_uc.uc_flags = _UC_SIGMASK;
1.60      ad        370:        frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK)
1.53      uwe       371:                ? _UC_SETSTACK : _UC_CLRSTACK;
                    372:        memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack));
1.60      ad        373:        sendsig_reset(l, sig);
1.71      ad        374:        mutex_exit(p->p_lock);
1.53      uwe       375:        cpu_getmcontext(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags);
1.60      ad        376:        error = copyout(&frame, fp, sizeof(frame));
1.71      ad        377:        mutex_enter(p->p_lock);
1.53      uwe       378:
1.60      ad        379:        if (error != 0) {
1.53      uwe       380:                /*
                    381:                 * Process has trashed its stack; give it an illegal
                    382:                 * instruction to halt it in its tracks.
                    383:                 */
                    384:                sigexit(l, SIGILL);
                    385:                /* NOTREACHED */
                    386:        }
                    387:
                    388:        tf->tf_r4 = sig;                /* "signum" argument for handler */
                    389:        tf->tf_r5 = (int)&fp->sf_si;    /* "sip" argument for handler */
                    390:        tf->tf_r6 = (int)&fp->sf_uc;    /* "ucp" argument for handler */
                    391:        tf->tf_spc = (int)catcher;
                    392:        tf->tf_r15 = (int)fp;
                    393:        tf->tf_pr = (int)ps->sa_sigdesc[sig].sd_tramp;
                    394:
                    395:        /* Remember if we're now on the signal stack. */
1.1       tsubai    396:        if (onstack)
1.60      ad        397:                l->l_sigstk.ss_flags |= SS_ONSTACK;
1.1       tsubai    398: }
                    399:
1.46      thorpej   400: void
1.79      dsl       401: cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags)
1.46      thorpej   402: {
                    403:        const struct trapframe *tf = l->l_md.md_regs;
                    404:        __greg_t *gr = mcp->__gregs;
1.48      nathanw   405:        __greg_t ras_pc;
1.46      thorpej   406:
                    407:        /* Save register context. */
1.74      uwe       408:        gr[_REG_GBR]    = tf->tf_gbr;
1.46      thorpej   409:        gr[_REG_PC]     = tf->tf_spc;
                    410:        gr[_REG_SR]     = tf->tf_ssr;
                    411:        gr[_REG_MACL]   = tf->tf_macl;
                    412:        gr[_REG_MACH]   = tf->tf_mach;
                    413:        gr[_REG_PR]     = tf->tf_pr;
                    414:        gr[_REG_R14]    = tf->tf_r14;
                    415:        gr[_REG_R13]    = tf->tf_r13;
                    416:        gr[_REG_R12]    = tf->tf_r12;
                    417:        gr[_REG_R11]    = tf->tf_r11;
                    418:        gr[_REG_R10]    = tf->tf_r10;
                    419:        gr[_REG_R9]     = tf->tf_r9;
                    420:        gr[_REG_R8]     = tf->tf_r8;
                    421:        gr[_REG_R7]     = tf->tf_r7;
                    422:        gr[_REG_R6]     = tf->tf_r6;
                    423:        gr[_REG_R5]     = tf->tf_r5;
                    424:        gr[_REG_R4]     = tf->tf_r4;
                    425:        gr[_REG_R3]     = tf->tf_r3;
                    426:        gr[_REG_R2]     = tf->tf_r2;
                    427:        gr[_REG_R1]     = tf->tf_r1;
                    428:        gr[_REG_R0]     = tf->tf_r0;
                    429:        gr[_REG_R15]    = tf->tf_r15;
1.48      nathanw   430:
                    431:        if ((ras_pc = (__greg_t)ras_lookup(l->l_proc,
1.62      christos  432:            (void *) gr[_REG_PC])) != -1)
1.48      nathanw   433:                gr[_REG_PC] = ras_pc;
                    434:
1.46      thorpej   435:        *flags |= _UC_CPU;
                    436:
                    437:        /* FPU context is currently not handled by the kernel. */
                    438:        memset(&mcp->__fpregs, 0, sizeof (mcp->__fpregs));
                    439: }
                    440:
                    441: int
1.79      dsl       442: cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
1.46      thorpej   443: {
                    444:        struct trapframe *tf = l->l_md.md_regs;
                    445:        const __greg_t *gr = mcp->__gregs;
1.60      ad        446:        struct proc *p = l->l_proc;
1.46      thorpej   447:
                    448:        /* Restore register context, if any. */
                    449:        if ((flags & _UC_CPU) != 0) {
                    450:                /* Check for security violations. */
                    451:                if (((tf->tf_ssr ^ gr[_REG_SR]) & PSL_USERSTATIC) != 0)
                    452:                        return (EINVAL);
1.64      uwe       453:
1.74      uwe       454:                tf->tf_gbr    = gr[_REG_GBR];
1.46      thorpej   455:                tf->tf_spc    = gr[_REG_PC];
                    456:                tf->tf_ssr    = gr[_REG_SR];
                    457:                tf->tf_macl   = gr[_REG_MACL];
                    458:                tf->tf_mach   = gr[_REG_MACH];
                    459:                tf->tf_pr     = gr[_REG_PR];
                    460:                tf->tf_r14    = gr[_REG_R14];
                    461:                tf->tf_r13    = gr[_REG_R13];
                    462:                tf->tf_r12    = gr[_REG_R12];
                    463:                tf->tf_r11    = gr[_REG_R11];
                    464:                tf->tf_r10    = gr[_REG_R10];
                    465:                tf->tf_r9     = gr[_REG_R9];
                    466:                tf->tf_r8     = gr[_REG_R8];
                    467:                tf->tf_r7     = gr[_REG_R7];
                    468:                tf->tf_r6     = gr[_REG_R6];
                    469:                tf->tf_r5     = gr[_REG_R5];
                    470:                tf->tf_r4     = gr[_REG_R4];
                    471:                tf->tf_r3     = gr[_REG_R3];
                    472:                tf->tf_r2     = gr[_REG_R2];
                    473:                tf->tf_r1     = gr[_REG_R1];
                    474:                tf->tf_r0     = gr[_REG_R0];
                    475:                tf->tf_r15    = gr[_REG_R15];
1.91      joerg     476:
                    477:                lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_GBR]);
1.46      thorpej   478:        }
1.53      uwe       479:
                    480: #if 0
                    481:        /* XXX: FPU context is currently not handled by the kernel. */
                    482:        if (flags & _UC_FPU) {
                    483:                /* TODO */;
                    484:        }
                    485: #endif
                    486:
1.71      ad        487:        mutex_enter(p->p_lock);
1.53      uwe       488:        if (flags & _UC_SETSTACK)
1.60      ad        489:                l->l_sigstk.ss_flags |= SS_ONSTACK;
1.53      uwe       490:        if (flags & _UC_CLRSTACK)
1.60      ad        491:                l->l_sigstk.ss_flags &= ~SS_ONSTACK;
1.71      ad        492:        mutex_exit(p->p_lock);
1.46      thorpej   493:
                    494:        return (0);
                    495: }
                    496:
1.1       tsubai    497: /*
                    498:  * Clear registers on exec
                    499:  */
                    500: void
1.85      matt      501: setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
1.1       tsubai    502: {
1.40      uch       503:        struct trapframe *tf;
1.1       tsubai    504:
1.89      uwe       505:        l->l_md.md_flags &= ~(MDP_USEDFPU | MDP_SSTEP);
1.1       tsubai    506:
1.46      thorpej   507:        tf = l->l_md.md_regs;
1.1       tsubai    508:
1.73      uwe       509:        tf->tf_ssr = PSL_USERSET;
                    510:        tf->tf_spc = pack->ep_entry;
                    511:        tf->tf_pr = 0;
                    512:
                    513:        tf->tf_gbr = 0;
                    514:        tf->tf_macl = 0;
                    515:        tf->tf_mach = 0;
                    516:
1.1       tsubai    517:        tf->tf_r0 = 0;
                    518:        tf->tf_r1 = 0;
                    519:        tf->tf_r2 = 0;
                    520:        tf->tf_r3 = 0;
1.62      christos  521:        tf->tf_r4 = fuword((void *)stack);      /* argc */
1.40      uch       522:        tf->tf_r5 = stack + 4;                  /* argv */
                    523:        tf->tf_r6 = stack + 4 * tf->tf_r4 + 8;  /* envp */
1.1       tsubai    524:        tf->tf_r7 = 0;
                    525:        tf->tf_r8 = 0;
1.92      joerg     526:        tf->tf_r9 = l->l_proc->p_psstrp;
1.1       tsubai    527:        tf->tf_r10 = 0;
                    528:        tf->tf_r11 = 0;
                    529:        tf->tf_r12 = 0;
                    530:        tf->tf_r13 = 0;
                    531:        tf->tf_r14 = 0;
                    532:        tf->tf_r15 = stack;
1.28      uch       533: }
                    534:
                    535: /*
                    536:  * Jump to reset vector.
                    537:  */
                    538: void
1.80      cegger    539: cpu_reset(void)
1.28      uch       540: {
                    541:
                    542:        _cpu_exception_suspend();
1.40      uch       543:        _reg_write_4(SH_(EXPEVT), EXPEVT_RESET_MANUAL);
1.28      uch       544:
1.58      uwe       545: #ifndef __lint__
                    546:        goto *(void *)0xa0000000;
                    547: #endif
1.29      uch       548:        /* NOTREACHED */
1.1       tsubai    549: }
1.91      joerg     550:
                    551: int
                    552: cpu_lwp_setprivate(lwp_t *l, void *addr)
                    553: {
                    554:
                    555:        l->l_md.md_regs->tf_gbr = (int)addr;
                    556:        return 0;
                    557: }
1.93      dyoung    558:

CVSweb <webmaster@jp.NetBSD.org>