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>