Annotation of sys/arch/sh/sh/sh_machdep.c, Revision 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