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>