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>