Annotation of sys/arch/sh/sh/sh_machdep.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: sh_machdep.c,v 1.16 2007/06/06 17:15:12 deraadt Exp $ */
2: /* $NetBSD: sh3_machdep.c,v 1.59 2006/03/04 01:13:36 uwe Exp $ */
3:
4: /*
5: * Copyright (c) 2007 Miodrag Vallat.
6: *
7: * Permission to use, copy, modify, and distribute this software for any
8: * purpose with or without fee is hereby granted, provided that the above
9: * copyright notice, this permission notice, and the disclaimer below
10: * appear in all copies.
11: *
12: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19: */
20: /*-
21: * Copyright (c) 1996, 1997, 1998, 2002 The NetBSD Foundation, Inc.
22: * All rights reserved.
23: *
24: * This code is derived from software contributed to The NetBSD Foundation
25: * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
26: * Simulation Facility, NASA Ames Research Center.
27: *
28: * Redistribution and use in source and binary forms, with or without
29: * modification, are permitted provided that the following conditions
30: * are met:
31: * 1. Redistributions of source code must retain the above copyright
32: * notice, this list of conditions and the following disclaimer.
33: * 2. Redistributions in binary form must reproduce the above copyright
34: * notice, this list of conditions and the following disclaimer in the
35: * documentation and/or other materials provided with the distribution.
36: * 3. All advertising materials mentioning features or use of this software
37: * must display the following acknowledgement:
38: * This product includes software developed by the NetBSD
39: * Foundation, Inc. and its contributors.
40: * 4. Neither the name of The NetBSD Foundation nor the names of its
41: * contributors may be used to endorse or promote products derived
42: * from this software without specific prior written permission.
43: *
44: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
45: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
46: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
48: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
50: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
51: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
52: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
54: * POSSIBILITY OF SUCH DAMAGE.
55: */
56: /*-
57: * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
58: * All rights reserved.
59: *
60: * This code is derived from software contributed to Berkeley by
61: * William Jolitz.
62: *
63: * Redistribution and use in source and binary forms, with or without
64: * modification, are permitted provided that the following conditions
65: * are met:
66: * 1. Redistributions of source code must retain the above copyright
67: * notice, this list of conditions and the following disclaimer.
68: * 2. Redistributions in binary form must reproduce the above copyright
69: * notice, this list of conditions and the following disclaimer in the
70: * documentation and/or other materials provided with the distribution.
71: * 3. Neither the name of the University nor the names of its contributors
72: * may be used to endorse or promote products derived from this software
73: * without specific prior written permission.
74: *
75: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
76: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
77: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
78: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
79: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
80: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
81: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
82: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
83: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
84: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85: * SUCH DAMAGE.
86: *
87: * @(#)machdep.c 7.4 (Berkeley) 6/3/91
88: */
89:
90: #include <sys/param.h>
91: #include <sys/systm.h>
92:
93: #include <sys/buf.h>
94: #include <sys/exec.h>
95: #include <sys/kernel.h>
96: #include <sys/malloc.h>
97: #include <sys/mount.h>
98: #include <sys/proc.h>
99: #include <sys/signalvar.h>
100: #include <sys/syscallargs.h>
101: #include <sys/user.h>
102: #include <sys/sched.h>
103: #include <sys/msg.h>
104: #include <sys/conf.h>
105: #include <sys/core.h>
106: #include <sys/kcore.h>
107: #include <sys/reboot.h>
108:
109: #include <uvm/uvm_extern.h>
110:
111: #include <dev/cons.h>
112:
113: #include <sh/cache.h>
114: #include <sh/clock.h>
115: #include <sh/locore.h>
116: #include <sh/mmu.h>
117: #include <sh/trap.h>
118: #include <sh/intr.h>
119: #include <sh/kcore.h>
120:
121: #ifndef BUFCACHEPERCENT
122: #define BUFCACHEPERCENT 5
123: #endif
124:
125: #ifdef BUFPAGES
126: int bufpages = BUFPAGES;
127: #else
128: int bufpages = 0;
129: #endif
130: int bufcachepercent = BUFCACHEPERCENT;
131:
132: /* Our exported CPU info; we can have only one. */
133: int cpu_arch;
134: int cpu_product;
135: char cpu_model[120];
136:
137: struct vm_map *exec_map;
138: struct vm_map *phys_map;
139:
140: int physmem;
141: struct user *proc0paddr; /* init_main.c use this. */
142: struct pcb *curpcb;
143: struct md_upte *curupte; /* SH3 wired u-area hack */
144:
145: #define VBR (u_int8_t *)SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN)
146: vaddr_t ram_start = SH3_PHYS_TO_P1SEG(IOM_RAM_BEGIN);
147: /* exception handler holder (sh/sh/vectors.S) */
148: extern char sh_vector_generic[], sh_vector_generic_end[];
149: extern char sh_vector_interrupt[], sh_vector_interrupt_end[];
150: #ifdef SH3
151: extern char sh3_vector_tlbmiss[], sh3_vector_tlbmiss_end[];
152: #endif
153: #ifdef SH4
154: extern char sh4_vector_tlbmiss[], sh4_vector_tlbmiss_end[];
155: #endif
156:
157: caddr_t allocsys(caddr_t);
158:
159: /*
160: * These variables are needed by /sbin/savecore
161: */
162: u_int32_t dumpmag = 0x8fca0101; /* magic number */
163: u_int dumpsize; /* pages */
164: long dumplo; /* blocks */
165: cpu_kcore_hdr_t cpu_kcore_hdr;
166:
167: void
168: sh_cpu_init(int arch, int product)
169: {
170: /* CPU type */
171: cpu_arch = arch;
172: cpu_product = product;
173:
174: #if defined(SH3) && defined(SH4)
175: /* Set register addresses */
176: sh_devreg_init();
177: #endif
178: /* Cache access ops. */
179: sh_cache_init();
180:
181: /* MMU access ops. */
182: sh_mmu_init();
183:
184: /* Hardclock, RTC initialize. */
185: machine_clock_init();
186:
187: /* ICU initiailze. */
188: intc_init();
189:
190: /* Exception vector. */
191: memcpy(VBR + 0x100, sh_vector_generic,
192: sh_vector_generic_end - sh_vector_generic);
193: #ifdef SH3
194: if (CPU_IS_SH3)
195: memcpy(VBR + 0x400, sh3_vector_tlbmiss,
196: sh3_vector_tlbmiss_end - sh3_vector_tlbmiss);
197: #endif
198: #ifdef SH4
199: if (CPU_IS_SH4)
200: memcpy(VBR + 0x400, sh4_vector_tlbmiss,
201: sh4_vector_tlbmiss_end - sh4_vector_tlbmiss);
202: #endif
203: memcpy(VBR + 0x600, sh_vector_interrupt,
204: sh_vector_interrupt_end - sh_vector_interrupt);
205:
206: if (!SH_HAS_UNIFIED_CACHE)
207: sh_icache_sync_all();
208:
209: __asm volatile("ldc %0, vbr" :: "r"(VBR));
210:
211: /* kernel stack setup */
212: __sh_switch_resume = CPU_IS_SH3 ? sh3_switch_resume : sh4_switch_resume;
213:
214: /* Set page size (4KB) */
215: uvm_setpagesize();
216: }
217:
218: /*
219: * void sh_proc0_init(void):
220: * Setup proc0 u-area.
221: */
222: void
223: sh_proc0_init()
224: {
225: struct switchframe *sf;
226: vaddr_t u;
227:
228: /* Steal process0 u-area */
229: u = uvm_pageboot_alloc(USPACE);
230: memset((void *)u, 0, USPACE);
231:
232: /* Setup proc0 */
233: proc0paddr = (struct user *)u;
234: proc0.p_addr = proc0paddr;
235: /*
236: * u-area map:
237: * |user| .... | .................. |
238: * | PAGE_SIZE | USPACE - PAGE_SIZE |
239: * frame top stack top
240: * current frame ... r6_bank
241: * stack top ... r7_bank
242: * current stack ... r15
243: */
244: curpcb = proc0.p_md.md_pcb = &proc0.p_addr->u_pcb;
245: curupte = proc0.p_md.md_upte;
246:
247: sf = &curpcb->pcb_sf;
248: sf->sf_r6_bank = u + PAGE_SIZE;
249: sf->sf_r7_bank = sf->sf_r15 = u + USPACE;
250: __asm volatile("ldc %0, r6_bank" :: "r"(sf->sf_r6_bank));
251: __asm volatile("ldc %0, r7_bank" :: "r"(sf->sf_r7_bank));
252:
253: proc0.p_md.md_regs = (struct trapframe *)sf->sf_r6_bank - 1;
254: #ifdef KSTACK_DEBUG
255: memset((char *)(u + sizeof(struct user)), 0x5a,
256: PAGE_SIZE - sizeof(struct user));
257: memset((char *)(u + PAGE_SIZE), 0xa5, USPACE - PAGE_SIZE);
258: #endif /* KSTACK_DEBUG */
259: }
260:
261: void
262: sh_startup()
263: {
264: vaddr_t minaddr, maxaddr;
265: caddr_t sysbase;
266: caddr_t size;
267:
268: printf("%s", version);
269: if (*cpu_model != '\0')
270: printf("%s\n", cpu_model);
271: #ifdef DEBUG
272: printf("general exception handler:\t%d byte\n",
273: sh_vector_generic_end - sh_vector_generic);
274: printf("TLB miss exception handler:\t%d byte\n",
275: #if defined(SH3) && defined(SH4)
276: CPU_IS_SH3 ? sh3_vector_tlbmiss_end - sh3_vector_tlbmiss :
277: sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
278: #elif defined(SH3)
279: sh3_vector_tlbmiss_end - sh3_vector_tlbmiss
280: #elif defined(SH4)
281: sh4_vector_tlbmiss_end - sh4_vector_tlbmiss
282: #endif
283: );
284: printf("interrupt exception handler:\t%d byte\n",
285: sh_vector_interrupt_end - sh_vector_interrupt);
286: #endif /* DEBUG */
287:
288: printf("real mem = %u (%uK)\n", ctob(physmem), ctob(physmem) / 1024);
289:
290: /*
291: * Find out how much space we need, allocate it,
292: * and then give everything true virtual addresses.
293: */
294: size = allocsys(NULL);
295: sysbase = (caddr_t)uvm_km_zalloc(kernel_map, round_page((vaddr_t)size));
296: if (sysbase == 0)
297: panic("sh_startup: no room for system tables; %d required",
298: (u_int)size);
299: if ((caddr_t)((allocsys(sysbase) - sysbase)) != size)
300: panic("cpu_startup: system table size inconsistency");
301:
302: /*
303: * Determine how many buffers to allocate.
304: * We allocate bufcachepercent% of memory for buffer space.
305: */
306: if (bufpages == 0)
307: bufpages = physmem * bufcachepercent / 100;
308:
309: /* Restrict to at most 25% filled kvm */
310: if (bufpages >
311: (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
312: bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
313: PAGE_SIZE / 4;
314:
315: /*
316: * Allocate a submap for exec arguments. This map effectively
317: * limits the number of processes exec'ing at any time.
318: */
319: minaddr = vm_map_min(kernel_map);
320: exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
321: 16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
322:
323: /*
324: * Allocate a submap for physio
325: */
326: phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
327: VM_PHYS_SIZE, 0, FALSE, NULL);
328:
329: /*
330: * Set up buffers, so they can be used to read disk labels.
331: */
332: bufinit();
333:
334: printf("avail mem = %u (%uK)\n", ptoa(uvmexp.free),
335: ptoa(uvmexp.free) / 1024);
336:
337: if (boothowto & RB_CONFIG) {
338: #ifdef BOOT_CONFIG
339: user_config();
340: #else
341: printf("kernel does not support -c; continuing..\n");
342: #endif
343: }
344: }
345:
346: /*
347: * Allocate space for system data structures. We are given
348: * a starting virtual address and we return a final virtual
349: * address; along the way we set each data structure pointer.
350: *
351: * We call allocsys() with 0 to find out how much space we want,
352: * allocate that much and fill it with zeroes, and then call
353: * allocsys() again with the correct base virtual address.
354: */
355: caddr_t
356: allocsys(caddr_t v)
357: {
358: #define valloc(name, type, num) v = (caddr_t)(((name) = (type *)v) + (num))
359:
360: #ifdef SYSVMSG
361: valloc(msgpool, char, msginfo.msgmax);
362: valloc(msgmaps, struct msgmap, msginfo.msgseg);
363: valloc(msghdrs, struct msg, msginfo.msgtql);
364: valloc(msqids, struct msqid_ds, msginfo.msgmni);
365: #endif
366:
367: return v;
368: }
369:
370: void
371: dumpconf(void)
372: {
373: cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
374: u_int dumpextra, totaldumpsize; /* in disk blocks */
375: u_int seg, nblks;
376:
377: if (dumpdev == NODEV ||
378: (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
379: return;
380: if (nblks <= ctod(1))
381: return;
382:
383: dumpsize = 0;
384: for (seg = 0; seg < h->kcore_nsegs; seg++)
385: dumpsize += atop(h->kcore_segs[seg].size);
386: dumpextra = cpu_dumpsize();
387:
388: /* Always skip the first block, in case there is a label there. */
389: if (dumplo < btodb(1));
390: dumplo = btodb(1);
391:
392: /* Put dump at the end of the partition, and make it fit. */
393: totaldumpsize = ctod(dumpsize) + dumpextra;
394: if (totaldumpsize > nblks - dumplo) {
395: totaldumpsize = dbtob(nblks - dumplo);
396: dumpsize = dtoc(totaldumpsize - dumpextra);
397: }
398: if (dumplo < nblks - totaldumpsize)
399: dumplo = nblks - totaldumpsize;
400: }
401:
402: void
403: dumpsys()
404: {
405: cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
406: daddr64_t blkno;
407: int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
408: u_int page = 0;
409: paddr_t dumppa;
410: u_int seg;
411: int rc;
412: extern int msgbufmapped;
413:
414: /* Don't record dump messages in msgbuf. */
415: msgbufmapped = 0;
416:
417: /* Make sure dump settings are valid. */
418: if (dumpdev == NODEV)
419: return;
420: if (dumpsize == 0) {
421: dumpconf();
422: if (dumpsize == 0)
423: return;
424: }
425: if (dumplo <= 0) {
426: printf("\ndump to dev 0x%x not possible, not enough space\n",
427: dumpdev);
428: return;
429: }
430:
431: dump = bdevsw[major(dumpdev)].d_dump;
432: blkno = dumplo;
433:
434: printf("\ndumping to dev 0x%x offset %ld\n", dumpdev, dumplo);
435:
436: printf("dump ");
437:
438: /* Write dump header */
439: rc = cpu_dump(dump, &blkno);
440: if (rc != 0)
441: goto bad;
442:
443: for (seg = 0; seg < h->kcore_nsegs; seg++) {
444: u_int pagesleft;
445:
446: pagesleft = atop(h->kcore_segs[seg].size);
447: dumppa = (paddr_t)h->kcore_segs[seg].start;
448:
449: while (pagesleft != 0) {
450: u_int npages;
451:
452: #define NPGMB atop(1024 * 1024)
453: if (page != 0 && (page % NPGMB) == 0)
454: printf("%u ", page / NPGMB);
455:
456: /* do not dump more than 1MB at once */
457: npages = min(pagesleft, NPGMB);
458: #undef NPGMB
459: npages = min(npages, dumpsize);
460:
461: rc = (*dump)(dumpdev, blkno,
462: (caddr_t)SH3_PHYS_TO_P2SEG(dumppa), ptoa(npages));
463: if (rc != 0)
464: goto bad;
465:
466: pagesleft -= npages;
467: dumppa += ptoa(npages);
468: page += npages;
469: dumpsize -= npages;
470: if (dumpsize == 0)
471: goto bad; /* if truncated dump */
472: blkno += ctod(npages);
473: }
474: }
475: bad:
476: switch (rc) {
477: case 0:
478: printf("succeeded\n");
479: break;
480: case ENXIO:
481: printf("device bad\n");
482: break;
483: case EFAULT:
484: printf("device not ready\n");
485: break;
486: case EINVAL:
487: printf("area improper\n");
488: break;
489: case EIO:
490: printf("I/O error\n");
491: break;
492: case EINTR:
493: printf("aborted\n");
494: break;
495: default:
496: printf("error %d\n", rc);
497: break;
498: }
499:
500: /* make sure console can output our last message */
501: delay(1 * 1000 * 1000);
502: }
503:
504: /*
505: * Signal frame.
506: */
507: struct sigframe {
508: #if 0 /* in registers on entry to signal trampoline */
509: int sf_signum; /* r4 - "signum" argument for handler */
510: siginfo_t *sf_sip; /* r5 - "sip" argument for handler */
511: struct sigcontext *sf_ucp; /* r6 - "ucp" argument for handler */
512: #endif
513: struct sigcontext sf_uc; /* actual context */
514: siginfo_t sf_si;
515: };
516:
517: /*
518: * Send an interrupt to process.
519: */
520: void
521: sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
522: union sigval val)
523: {
524: struct proc *p = curproc;
525: struct sigframe *fp, frame;
526: struct trapframe *tf = p->p_md.md_regs;
527: struct sigacts *ps = p->p_sigacts;
528: siginfo_t *sip;
529: int onstack;
530:
531: onstack = ps->ps_sigstk.ss_flags & SS_ONSTACK;
532: if ((ps->ps_flags & SAS_ALTSTACK) && onstack == 0 &&
533: (ps->ps_sigonstack & sigmask(sig))) {
534: fp = (struct sigframe *)((vaddr_t)ps->ps_sigstk.ss_sp +
535: ps->ps_sigstk.ss_size);
536: ps->ps_sigstk.ss_flags |= SS_ONSTACK;
537: } else
538: fp = (void *)p->p_md.md_regs->tf_r15;
539: --fp;
540:
541:
542: bzero(&frame, sizeof(frame));
543:
544: if (ps->ps_siginfo & sigmask(sig)) {
545: initsiginfo(&frame.sf_si, sig, code, type, val);
546: sip = &fp->sf_si;
547: } else
548: sip = NULL;
549:
550: /* Save register context. */
551: frame.sf_uc.sc_reg.r_spc = tf->tf_spc;
552: frame.sf_uc.sc_reg.r_ssr = tf->tf_ssr;
553: frame.sf_uc.sc_reg.r_pr = tf->tf_pr;
554: frame.sf_uc.sc_reg.r_mach = tf->tf_mach;
555: frame.sf_uc.sc_reg.r_macl = tf->tf_macl;
556: frame.sf_uc.sc_reg.r_r15 = tf->tf_r15;
557: frame.sf_uc.sc_reg.r_r14 = tf->tf_r14;
558: frame.sf_uc.sc_reg.r_r13 = tf->tf_r13;
559: frame.sf_uc.sc_reg.r_r12 = tf->tf_r12;
560: frame.sf_uc.sc_reg.r_r11 = tf->tf_r11;
561: frame.sf_uc.sc_reg.r_r10 = tf->tf_r10;
562: frame.sf_uc.sc_reg.r_r9 = tf->tf_r9;
563: frame.sf_uc.sc_reg.r_r8 = tf->tf_r8;
564: frame.sf_uc.sc_reg.r_r7 = tf->tf_r7;
565: frame.sf_uc.sc_reg.r_r6 = tf->tf_r6;
566: frame.sf_uc.sc_reg.r_r5 = tf->tf_r5;
567: frame.sf_uc.sc_reg.r_r4 = tf->tf_r4;
568: frame.sf_uc.sc_reg.r_r3 = tf->tf_r3;
569: frame.sf_uc.sc_reg.r_r2 = tf->tf_r2;
570: frame.sf_uc.sc_reg.r_r1 = tf->tf_r1;
571: frame.sf_uc.sc_reg.r_r0 = tf->tf_r0;
572: #ifdef SH4
573: if (CPU_IS_SH4)
574: fpu_save(&frame.sf_uc.sc_fpreg);
575: #endif
576:
577: frame.sf_uc.sc_onstack = onstack;
578: frame.sf_uc.sc_expevt = tf->tf_expevt;
579: /* frame.sf_uc.sc_err = 0; */
580: frame.sf_uc.sc_mask = mask;
581:
582: if (copyout(&frame, fp, sizeof(frame)) != 0) {
583: /*
584: * Process has trashed its stack; give it an illegal
585: * instruction to halt it in its tracks.
586: */
587: sigexit(p, SIGILL);
588: /* NOTREACHED */
589: }
590:
591: tf->tf_r4 = sig; /* "signum" argument for handler */
592: tf->tf_r5 = (int)sip; /* "sip" argument for handler */
593: tf->tf_r6 = (int)&fp->sf_uc; /* "ucp" argument for handler */
594: tf->tf_spc = (int)catcher;
595: tf->tf_r15 = (int)fp;
596: tf->tf_pr = (int)p->p_sigcode;
597: }
598:
599: /*
600: * System call to cleanup state after a signal
601: * has been taken. Reset signal mask and
602: * stack state from context left by sendsig (above).
603: * Return to previous pc and psl as specified by
604: * context left by sendsig. Check carefully to
605: * make sure that the user has not modified the
606: * psl to gain improper privileges or to cause
607: * a machine fault.
608: */
609: int
610: sys_sigreturn(struct proc *p, void *v, register_t *retval)
611: {
612: struct sys_sigreturn_args /* {
613: syscallarg(struct sigcontext *) sigcntxp;
614: } */ *uap = v;
615: struct sigcontext *scp, context;
616: struct trapframe *tf;
617: int error;
618:
619: /*
620: * The trampoline code hands us the context.
621: * It is unsafe to keep track of it ourselves, in the event that a
622: * program jumps out of a signal handler.
623: */
624: scp = SCARG(uap, sigcntxp);
625: if ((error = copyin((caddr_t)scp, &context, sizeof(*scp))) != 0)
626: return (error);
627:
628: /* Restore signal context. */
629: tf = p->p_md.md_regs;
630:
631: /* Check for security violations. */
632: if (((context.sc_reg.r_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0)
633: return (EINVAL);
634:
635: tf->tf_spc = context.sc_reg.r_spc;
636: tf->tf_ssr = context.sc_reg.r_ssr;
637: tf->tf_macl = context.sc_reg.r_macl;
638: tf->tf_mach = context.sc_reg.r_mach;
639: tf->tf_pr = context.sc_reg.r_pr;
640: tf->tf_r13 = context.sc_reg.r_r13;
641: tf->tf_r12 = context.sc_reg.r_r12;
642: tf->tf_r11 = context.sc_reg.r_r11;
643: tf->tf_r10 = context.sc_reg.r_r10;
644: tf->tf_r9 = context.sc_reg.r_r9;
645: tf->tf_r8 = context.sc_reg.r_r8;
646: tf->tf_r7 = context.sc_reg.r_r7;
647: tf->tf_r6 = context.sc_reg.r_r6;
648: tf->tf_r5 = context.sc_reg.r_r5;
649: tf->tf_r4 = context.sc_reg.r_r4;
650: tf->tf_r3 = context.sc_reg.r_r3;
651: tf->tf_r2 = context.sc_reg.r_r2;
652: tf->tf_r1 = context.sc_reg.r_r1;
653: tf->tf_r0 = context.sc_reg.r_r0;
654: tf->tf_r15 = context.sc_reg.r_r15;
655: tf->tf_r14 = context.sc_reg.r_r14;
656:
657: #ifdef SH4
658: if (CPU_IS_SH4)
659: fpu_restore(&context.sc_fpreg);
660: #endif
661:
662: /* Restore signal stack. */
663: if (context.sc_onstack)
664: p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
665: else
666: p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
667: /* Restore signal mask. */
668: p->p_sigmask = context.sc_mask & ~sigcantmask;
669:
670: return (EJUSTRETURN);
671: }
672:
673: /*
674: * Clear registers on exec
675: */
676: void
677: setregs(struct proc *p, struct exec_package *pack, u_long stack,
678: register_t rval[2])
679: {
680: struct trapframe *tf;
681: struct pcb *pcb = p->p_md.md_pcb;
682:
683: p->p_md.md_flags &= ~MDP_USEDFPU;
684:
685: tf = p->p_md.md_regs;
686:
687: tf->tf_r0 = 0;
688: tf->tf_r1 = 0;
689: tf->tf_r2 = 0;
690: tf->tf_r3 = 0;
691: copyin((caddr_t)stack, &tf->tf_r4, sizeof(register_t)); /* argc */
692: tf->tf_r5 = stack + 4; /* argv */
693: tf->tf_r6 = stack + 4 * tf->tf_r4 + 8; /* envp */
694: tf->tf_r7 = 0;
695: tf->tf_r8 = 0;
696: tf->tf_r9 = (int)PS_STRINGS;
697: tf->tf_r10 = 0;
698: tf->tf_r11 = 0;
699: tf->tf_r12 = 0;
700: tf->tf_r13 = 0;
701: tf->tf_r14 = 0;
702: tf->tf_spc = pack->ep_entry;
703: tf->tf_ssr = PSL_USERSET;
704: tf->tf_r15 = stack;
705:
706: #ifdef SH4
707: if (CPU_IS_SH4) {
708: /*
709: * Clear floating point registers.
710: */
711: bzero(&pcb->pcb_fp, sizeof(pcb->pcb_fp));
712: fpu_restore(&pcb->pcb_fp);
713: }
714: #endif
715:
716: rval[1] = 0;
717: }
718:
719: void
720: setrunqueue(struct proc *p)
721: {
722: int whichq = p->p_priority / PPQ;
723: struct prochd *q;
724: struct proc *prev;
725:
726: #ifdef DIAGNOSTIC
727: if (p->p_back != NULL || p->p_wchan != NULL || p->p_stat != SRUN)
728: panic("setrunqueue");
729: #endif
730: q = &qs[whichq];
731: prev = q->ph_rlink;
732: p->p_forw = (struct proc *)q;
733: q->ph_rlink = p;
734: prev->p_forw = p;
735: p->p_back = prev;
736: whichqs |= 1 << whichq;
737: }
738:
739: void
740: remrunqueue(struct proc *p)
741: {
742: struct proc *prev, *next;
743: int whichq = p->p_priority / PPQ;
744:
745: #ifdef DIAGNOSTIC
746: if (((whichqs & (1 << whichq)) == 0))
747: panic("remrunqueue: bit %d not set", whichq);
748: #endif
749: prev = p->p_back;
750: p->p_back = NULL;
751: next = p->p_forw;
752: prev->p_forw = next;
753: next->p_back = prev;
754: if (prev == next)
755: whichqs &= ~(1 << whichq);
756: }
757:
758: /*
759: * Jump to reset vector.
760: */
761: void
762: cpu_reset()
763: {
764: _cpu_exception_suspend();
765: _reg_write_4(SH_(EXPEVT), EXPEVT_RESET_MANUAL);
766:
767: #ifndef __lint__
768: goto *(void *)0xa0000000;
769: #endif
770: /* NOTREACHED */
771: }
CVSweb