Annotation of sys/arch/mvmeppc/mvmeppc/machdep.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: machdep.c,v 1.53 2007/05/26 20:26:51 pedro Exp $ */
! 2: /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
! 3:
! 4: /*
! 5: * Copyright (C) 1995, 1996 Wolfgang Solfrank.
! 6: * Copyright (C) 1995, 1996 TooLs GmbH.
! 7: * All rights reserved.
! 8: *
! 9: * Redistribution and use in source and binary forms, with or without
! 10: * modification, are permitted provided that the following conditions
! 11: * are met:
! 12: * 1. Redistributions of source code must retain the above copyright
! 13: * notice, this list of conditions and the following disclaimer.
! 14: * 2. Redistributions in binary form must reproduce the above copyright
! 15: * notice, this list of conditions and the following disclaimer in the
! 16: * documentation and/or other materials provided with the distribution.
! 17: * 3. All advertising materials mentioning features or use of this software
! 18: * must display the following acknowledgement:
! 19: * This product includes software developed by TooLs GmbH.
! 20: * 4. The name of TooLs GmbH may not be used to endorse or promote products
! 21: * derived from this software without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
! 24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 25: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 26: * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
! 27: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
! 28: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
! 29: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
! 30: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
! 31: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! 32: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 33: */
! 34:
! 35: #include <sys/param.h>
! 36: #include <sys/buf.h>
! 37: #include <sys/timeout.h>
! 38: #include <sys/exec.h>
! 39: #include <sys/malloc.h>
! 40: #include <sys/mbuf.h>
! 41: #include <sys/mount.h>
! 42: #include <sys/msgbuf.h>
! 43: #include <sys/proc.h>
! 44: #include <sys/signalvar.h>
! 45: #include <sys/reboot.h>
! 46: #include <sys/syscallargs.h>
! 47: #ifdef SYSVMSG
! 48: #include <sys/msg.h>
! 49: #endif
! 50: #include <sys/syslog.h>
! 51: #include <sys/extent.h>
! 52: #include <sys/systm.h>
! 53: #include <sys/user.h>
! 54:
! 55: #include <net/netisr.h>
! 56:
! 57: #include <machine/bat.h>
! 58: #include <machine/bugio.h>
! 59: #include <machine/pmap.h>
! 60: #include <machine/powerpc.h>
! 61: #include <machine/trap.h>
! 62: #include <machine/autoconf.h>
! 63: #include <machine/bus.h>
! 64: #include <machine/conf.h>
! 65: #include <machine/pio.h>
! 66: #include <machine/prom.h>
! 67:
! 68: #include <dev/cons.h>
! 69:
! 70: #include <uvm/uvm_extern.h>
! 71:
! 72: #ifdef DDB
! 73: #include <machine/db_machdep.h>
! 74: #include <ddb/db_access.h>
! 75: #include <ddb/db_sym.h>
! 76: #include <ddb/db_extern.h>
! 77: #endif
! 78:
! 79: void initppc(u_int, u_int, char *);
! 80: void dumpsys(void);
! 81: int lcsplx(int);
! 82: void myetheraddr(u_char *);
! 83:
! 84: /*
! 85: * Global variables used here and there
! 86: */
! 87: struct pcb *curpcb;
! 88: struct pmap *curpm;
! 89: struct proc *fpuproc;
! 90:
! 91: extern struct user *proc0paddr;
! 92:
! 93: /*
! 94: * This is to fake out the console routines, while booting.
! 95: */
! 96: cons_decl(boot);
! 97: #define bootcnpollc nullcnpollc
! 98:
! 99: static struct consdev bootcons = {
! 100: NULL,
! 101: NULL,
! 102: bootcngetc,
! 103: bootcnputc,
! 104: bootcnpollc,
! 105: NULL,
! 106: makedev(14, 0),
! 107: CN_NORMAL,
! 108: };
! 109:
! 110: /*
! 111: * Declare these as initialized data so we can patch them.
! 112: */
! 113: #ifndef BUFCACHEPERCENT
! 114: #define BUFCACHEPERCENT 5
! 115: #endif
! 116:
! 117: #ifdef BUFPAGES
! 118: int bufpages = BUFPAGES;
! 119: #else
! 120: int bufpages = 0;
! 121: #endif
! 122: int bufcachepercent = BUFCACHEPERCENT;
! 123:
! 124: struct bat battable[16];
! 125:
! 126: struct vm_map *exec_map = NULL;
! 127: struct vm_map *phys_map = NULL;
! 128:
! 129: int ppc_malloc_ok;
! 130:
! 131: #ifndef SYS_TYPE
! 132: /* XXX Hardwire it for now */
! 133: #define SYS_TYPE MVME
! 134: #endif
! 135:
! 136: int system_type = SYS_TYPE; /* XXX Hardwire it for now */
! 137:
! 138: struct firmware *fw = NULL;
! 139: extern struct firmware ppc1_firmware;
! 140:
! 141: caddr_t allocsys(caddr_t);
! 142:
! 143: /*
! 144: * Extent maps to manage I/O. Allocate storage for 8 regions in each,
! 145: * initially. Later devio_malloc_safe will indicate that it's safe to
! 146: * use malloc() to dynamically allocate region descriptors.
! 147: */
! 148: static long devio_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof (long)];
! 149: struct extent *devio_ex;
! 150: static int devio_malloc_safe = 0;
! 151:
! 152: void
! 153: initppc(startkernel, endkernel, args)
! 154: u_int startkernel, endkernel;
! 155: char *args;
! 156: {
! 157: extern void *trapcode; extern int trapsize;
! 158: extern void *dsitrap; extern int dsisize;
! 159: extern void *isitrap; extern int isisize;
! 160: extern void *alitrap; extern int alisize;
! 161: extern void *decrint; extern int decrsize;
! 162: extern void *tlbimiss; extern int tlbimsize;
! 163: extern void *tlbdlmiss; extern int tlbdlmsize;
! 164: extern void *tlbdsmiss; extern int tlbdsmsize;
! 165: #ifdef DDB
! 166: extern void *ddblow; extern int ddbsize;
! 167: #endif
! 168: extern void consinit(void);
! 169: extern void *msgbuf_addr;
! 170: int exc, scratch;
! 171:
! 172: proc0.p_addr = proc0paddr;
! 173: bzero(proc0.p_addr, sizeof *proc0.p_addr);
! 174:
! 175: fw = &ppc1_firmware; /* Just PPC1-Bug for now... */
! 176: buginit();
! 177:
! 178: curpcb = &proc0paddr->u_pcb;
! 179:
! 180: curpm = curpcb->pcb_pmreal = curpcb->pcb_pm = pmap_kernel();
! 181:
! 182: /* startup fake console driver. It will be replaced by consinit() */
! 183: cn_tab = &bootcons;
! 184:
! 185: /*
! 186: * Initialize BAT registers to unmapped to not generate
! 187: * overlapping mappings below.
! 188: */
! 189: ppc_mtibat0u(0);
! 190: ppc_mtibat1u(0);
! 191: ppc_mtibat2u(0);
! 192: ppc_mtibat3u(0);
! 193: ppc_mtdbat0u(0);
! 194: ppc_mtdbat1u(0);
! 195: ppc_mtdbat2u(0);
! 196: ppc_mtdbat3u(0);
! 197:
! 198: /*
! 199: * Set up initial BAT table
! 200: */
! 201: battable[0].batl = BATL(0x00000000, BAT_M);
! 202: battable[0].batu = BATU(0x00000000);
! 203:
! 204: /*
! 205: * Now setup fixed bat registers
! 206: *
! 207: * Note that we still run in real mode, and the BAT
! 208: * registers were cleared above.
! 209: */
! 210: /* IBAT0 used for initial 256 MB segment */
! 211: ppc_mtibat0l(battable[0].batl);
! 212: ppc_mtibat0u(battable[0].batu);
! 213:
! 214: /* DBAT0 used similar */
! 215: ppc_mtdbat0l(battable[0].batl);
! 216: ppc_mtdbat0u(battable[0].batu);
! 217:
! 218: /*
! 219: * Set up trap vectors
! 220: */
! 221: for (exc = EXC_RSVD; exc <= EXC_LAST; exc += 0x100) {
! 222: switch (exc) {
! 223: default:
! 224: bcopy(&trapcode, (void *)exc, (size_t)&trapsize);
! 225: break;
! 226: case EXC_EXI:
! 227: /*
! 228: * This one is (potentially) installed during autoconf
! 229: */
! 230: break;
! 231:
! 232: case EXC_DSI:
! 233: bcopy(&dsitrap, (void *)exc, (size_t)&dsisize);
! 234: break;
! 235: case EXC_ISI:
! 236: bcopy(&isitrap, (void *)exc, (size_t)&isisize);
! 237: break;
! 238: case EXC_ALI:
! 239: bcopy(&alitrap, (void *)exc, (size_t)&alisize);
! 240: break;
! 241: case EXC_DECR:
! 242: bcopy(&decrint, (void *)exc, (size_t)&decrsize);
! 243: break;
! 244: case EXC_IMISS:
! 245: bcopy(&tlbimiss, (void *)exc, (size_t)&tlbimsize);
! 246: break;
! 247: case EXC_DLMISS:
! 248: bcopy(&tlbdlmiss, (void *)exc, (size_t)&tlbdlmsize);
! 249: break;
! 250: case EXC_DSMISS:
! 251: bcopy(&tlbdsmiss, (void *)exc, (size_t)&tlbdsmsize);
! 252: break;
! 253: #ifdef DDB
! 254: case EXC_PGM:
! 255: case EXC_TRC:
! 256: case EXC_BPT:
! 257: bcopy(&ddblow, (void *)exc, (size_t)&ddbsize);
! 258: break;
! 259: #endif
! 260: }
! 261: }
! 262:
! 263: /* Grr, ALTIVEC_UNAVAIL is a vector not ~0xff aligned: 0x0f20 */
! 264: bcopy(&trapcode, (void *)0xf20, (size_t)&trapsize);
! 265:
! 266: /*
! 267: * since trapsize is > 0x20, we just overwrote the EXC_PERF handler
! 268: * since we do not use it, we will "share" it with the EXC_VEC,
! 269: * we dont support EXC_VEC either.
! 270: * should be a 'ba 0xf20 written' at address 0xf00, but we
! 271: * do not generate EXC_PERF exceptions...
! 272: */
! 273:
! 274: syncicache((void *)EXC_RST, EXC_LAST - EXC_RST + 0x100);
! 275:
! 276: /*
! 277: * Initialize pmap module.
! 278: */
! 279: uvmexp.pagesize = 4096;
! 280: uvm_setpagesize();
! 281: pmap_bootstrap(startkernel, endkernel);
! 282:
! 283: #if 1
! 284: /* MVME2[67]00 max out at 256MB, and we need BAT2 for now. */
! 285: #else
! 286: /* use BATs to map 1GB memory, no pageable BATs now */
! 287: if (physmem > btoc(0x10000000)) {
! 288: ppc_mtdbat1l(BATL(0x10000000, BAT_M));
! 289: ppc_mtdbat1u(BATU(0x10000000));
! 290: }
! 291: if (physmem > btoc(0x20000000)) {
! 292: ppc_mtdbat2l(BATL(0x20000000, BAT_M));
! 293: ppc_mtdbat2u(BATU(0x20000000));
! 294: }
! 295: if (physmem > btoc(0x30000000)) {
! 296: ppc_mtdbat3l(BATL(0x30000000, BAT_M));
! 297: ppc_mtdbat3u(BATU(0x30000000));
! 298: }
! 299: #endif
! 300:
! 301: /*
! 302: * Now enable translation (and machine checks/recoverable interrupts).
! 303: * This will also start using the exception vector prefix of 0x000.
! 304: */
! 305: (fw->vmon)();
! 306:
! 307: __asm__ volatile ("eieio; mfmsr %0; ori %0,%0,%1; mtmsr %0; sync;isync"
! 308: : "=r"(scratch) : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI));
! 309:
! 310: /*
! 311: * use the memory provided by pmap_bootstrap for message buffer
! 312: */
! 313: initmsgbuf(msgbuf_addr, MSGBUFSIZE);
! 314:
! 315: #ifdef DDB
! 316: #ifdef notyet
! 317: db_machine_init();
! 318: #endif
! 319: ddb_init();
! 320: #endif
! 321:
! 322: /*
! 323: * Set up extents for pci mappings
! 324: * Is this too late?
! 325: *
! 326: * what are good start and end values here??
! 327: * 0x0 - 0x80000000 mcu bus
! 328: * MAP A MAP B
! 329: * 0x80000000 - 0xbfffffff io 0x80000000 - 0xefffffff mem
! 330: * 0xc0000000 - 0xffffffff mem 0xf0000000 - 0xffffffff io
! 331: *
! 332: * of course bsd uses 0xe and 0xf
! 333: * So the BSD PPC memory map will look like this
! 334: * 0x0 - 0x80000000 memory (whatever is filled)
! 335: * 0x80000000 - 0xdfffffff (pci space, memory or io)
! 336: * 0xe0000000 - kernel vm segment
! 337: * 0xf0000000 - kernel map segment (user space mapped here)
! 338: */
! 339:
! 340: devio_ex = extent_create("devio", 0x80000000, 0xffffffff, M_DEVBUF,
! 341: (caddr_t)devio_ex_storage, sizeof(devio_ex_storage),
! 342: EX_NOCOALESCE|EX_NOWAIT);
! 343:
! 344: /*
! 345: * Now we can set up the console as mapping is enabled.
! 346: */
! 347: consinit();
! 348:
! 349: if (boothowto & RB_CONFIG) {
! 350: #ifdef BOOT_CONFIG
! 351: user_config();
! 352: #else
! 353: printf("kernel does not support -c; continuing..\n");
! 354: #endif
! 355: }
! 356:
! 357: #ifdef DDB
! 358: if (boothowto & RB_KDB)
! 359: Debugger();
! 360: #endif
! 361: }
! 362:
! 363: void
! 364: install_extint(handler)
! 365: void (*handler)(void);
! 366: {
! 367: extern caddr_t extint, extsize;
! 368: extern u_long extint_call;
! 369: u_long offset = (u_long)handler - (u_long)&extint_call;
! 370: int msr;
! 371:
! 372: #ifdef DIAGNOSTIC
! 373: if (offset > 0x1ffffff)
! 374: panic("install_extint: too far away");
! 375: #endif
! 376: msr = ppc_intr_disable();
! 377: extint_call = (extint_call & 0xfc000003) | offset;
! 378: bcopy(&extint, (void *)EXC_EXI, (size_t)&extsize);
! 379: syncicache((void *)&extint_call, sizeof extint_call);
! 380: syncicache((void *)EXC_EXI, (int)&extsize);
! 381: ppc_intr_enable(msr);
! 382: }
! 383:
! 384: /*
! 385: * Machine dependent startup code.
! 386: */
! 387: void
! 388: cpu_startup()
! 389: {
! 390: int sz;
! 391: caddr_t v;
! 392: vaddr_t minaddr, maxaddr;
! 393:
! 394: proc0.p_addr = proc0paddr;
! 395:
! 396: printf("%s", version);
! 397:
! 398: printf("real mem = %u (%uMB)\n", ctob(physmem),
! 399: ctob(physmem)/1024/1024);
! 400:
! 401: /*
! 402: * Find out how much space we need, allocate it,
! 403: * and then give everything true virtual addresses.
! 404: */
! 405: sz = (int)allocsys((caddr_t)0);
! 406: if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0)
! 407: panic("startup: no room for tables");
! 408: if (allocsys(v) - v != sz)
! 409: panic("startup: table size inconsistency");
! 410:
! 411: /*
! 412: * Determine how many buffers to allocate.
! 413: * We allocate bufcachepercent% of memory for buffer space.
! 414: */
! 415: if (bufpages == 0)
! 416: bufpages = physmem * bufcachepercent / 100;
! 417:
! 418: /* Restrict to at most 25% filled kvm */
! 419: if (bufpages >
! 420: (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
! 421: bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
! 422: PAGE_SIZE / 4;
! 423:
! 424: /*
! 425: * Allocate a submap for exec arguments. This map effectively
! 426: * limits the number of processes exec'ing at any time.
! 427: */
! 428: minaddr = vm_map_min(kernel_map);
! 429: exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 16 * NCARGS,
! 430: VM_MAP_PAGEABLE, FALSE, NULL);
! 431:
! 432: /*
! 433: * Allocate a submap for physio
! 434: */
! 435: phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
! 436: VM_PHYS_SIZE, 0, FALSE, NULL);
! 437: ppc_malloc_ok = 1;
! 438:
! 439: printf("avail mem = %lu (%luMB)\n", ptoa(uvmexp.free),
! 440: ptoa(uvmexp.free) / 1024 / 1024);
! 441:
! 442: /*
! 443: * Set up the buffers.
! 444: */
! 445: bufinit();
! 446:
! 447: /*
! 448: * Set up early mappings
! 449: */
! 450: devio_malloc_safe = 1;
! 451: nvram_map();
! 452: prep_bus_space_init();
! 453: }
! 454:
! 455: /*
! 456: * Allocate space for system data structures.
! 457: */
! 458: caddr_t
! 459: allocsys(v)
! 460: caddr_t v;
! 461: {
! 462: #define valloc(name, type, num) \
! 463: v = (caddr_t)(((name) = (type *)v) + (num))
! 464:
! 465: #ifdef SYSVMSG
! 466: valloc(msgpool, char, msginfo.msgmax);
! 467: valloc(msgmaps, struct msgmap, msginfo.msgseg);
! 468: valloc(msghdrs, struct msg, msginfo.msgtql);
! 469: valloc(msqids, struct msqid_ds, msginfo.msgmni);
! 470: #endif
! 471:
! 472: return v;
! 473: }
! 474:
! 475: /*
! 476: * consinit
! 477: * Initialize system console.
! 478: */
! 479: void
! 480: consinit()
! 481: {
! 482: static int cons_initted = 0;
! 483:
! 484: if (cons_initted)
! 485: return;
! 486: cn_tab = NULL;
! 487: cninit();
! 488: cons_initted = 1;
! 489: }
! 490:
! 491: /*
! 492: * Clear registers on exec
! 493: */
! 494: void
! 495: setregs(p, pack, stack, retval)
! 496: struct proc *p;
! 497: struct exec_package *pack;
! 498: u_long stack;
! 499: register_t *retval;
! 500: {
! 501: u_int32_t newstack;
! 502: u_int32_t pargs;
! 503: u_int32_t args[4];
! 504:
! 505: struct trapframe *tf = trapframe(p);
! 506: pargs = -roundup(-stack + 8, 16);
! 507: newstack = (u_int32_t)(pargs - 32);
! 508:
! 509: copyin ((void *)(VM_MAX_ADDRESS-0x10), &args, 0x10);
! 510:
! 511: bzero(tf, sizeof *tf);
! 512: tf->fixreg[1] = newstack;
! 513: tf->fixreg[3] = retval[0] = args[1]; /* XXX */
! 514: tf->fixreg[4] = retval[1] = args[0]; /* XXX */
! 515: tf->fixreg[5] = args[2]; /* XXX */
! 516: tf->fixreg[6] = args[3]; /* XXX */
! 517: tf->srr0 = pack->ep_entry;
! 518: tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT;
! 519: p->p_addr->u_pcb.pcb_flags = 0;
! 520: }
! 521:
! 522: /*
! 523: * Send a signal to process.
! 524: */
! 525: void
! 526: sendsig(catcher, sig, mask, code, type, val)
! 527: sig_t catcher;
! 528: int sig, mask;
! 529: u_long code;
! 530: int type;
! 531: union sigval val;
! 532: {
! 533: struct proc *p = curproc;
! 534: struct trapframe *tf;
! 535: struct sigframe *fp, frame;
! 536: struct sigacts *psp = p->p_sigacts;
! 537: int oldonstack;
! 538:
! 539: frame.sf_signum = sig;
! 540:
! 541: tf = trapframe(p);
! 542: oldonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
! 543:
! 544: /*
! 545: * Allocate stack space for signal handler.
! 546: */
! 547: if ((psp->ps_flags & SAS_ALTSTACK)
! 548: && !oldonstack
! 549: && (psp->ps_sigonstack & sigmask(sig))) {
! 550: fp = (struct sigframe *)(psp->ps_sigstk.ss_sp
! 551: + psp->ps_sigstk.ss_size);
! 552: psp->ps_sigstk.ss_flags |= SS_ONSTACK;
! 553: } else
! 554: fp = (struct sigframe *)tf->fixreg[1];
! 555:
! 556: fp = (struct sigframe *)((int)(fp - 1) & ~0xf);
! 557:
! 558: /*
! 559: * Generate signal context for SYS_sigreturn.
! 560: */
! 561: frame.sf_sc.sc_onstack = oldonstack;
! 562: frame.sf_sc.sc_mask = mask;
! 563: frame.sf_sip = NULL;
! 564: bcopy(tf, &frame.sf_sc.sc_frame, sizeof *tf);
! 565: if (psp->ps_siginfo & sigmask(sig)) {
! 566: frame.sf_sip = &fp->sf_si;
! 567: initsiginfo(&frame.sf_si, sig, code, type, val);
! 568: }
! 569: if (copyout(&frame, fp, sizeof frame) != 0)
! 570: sigexit(p, SIGILL);
! 571:
! 572:
! 573: tf->fixreg[1] = (int)fp;
! 574: tf->lr = (int)catcher;
! 575: tf->fixreg[3] = (int)sig;
! 576: tf->fixreg[4] = (psp->ps_siginfo & sigmask(sig)) ? (int)&fp->sf_si : 0;
! 577: tf->fixreg[5] = (int)&fp->sf_sc;
! 578: tf->srr0 = p->p_sigcode;
! 579:
! 580: #if WHEN_WE_ONLY_FLUSH_DATA_WHEN_DOING_PMAP_ENTER
! 581: pmap_extract(vm_map_pmap(&p->p_vmspace->vm_map),tf->srr0, &pa);
! 582: syncicache(pa, (p->p_emul->e_esigcode - p->p_emul->e_sigcode));
! 583: #endif
! 584: }
! 585:
! 586: /*
! 587: * System call to cleanup state after a signal handler returns.
! 588: */
! 589: int
! 590: sys_sigreturn(p, v, retval)
! 591: struct proc *p;
! 592: void *v;
! 593: register_t *retval;
! 594: {
! 595: struct sys_sigreturn_args /* {
! 596: syscallarg(struct sigcontext *) sigcntxp;
! 597: } */ *uap = v;
! 598: struct sigcontext sc;
! 599: struct trapframe *tf;
! 600: int error;
! 601:
! 602: if ((error = copyin(SCARG(uap, sigcntxp), &sc, sizeof sc)) != 0)
! 603: return error;
! 604: tf = trapframe(p);
! 605: if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC))
! 606: return EINVAL;
! 607: bcopy(&sc.sc_frame, tf, sizeof *tf);
! 608: if (sc.sc_onstack & 1)
! 609: p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
! 610: else
! 611: p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
! 612: p->p_sigmask = sc.sc_mask & ~sigcantmask;
! 613: return EJUSTRETURN;
! 614: }
! 615:
! 616: /*
! 617: * Machine dependent system variables.
! 618: * None for now.
! 619: */
! 620: int
! 621: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
! 622: int *name;
! 623: u_int namelen;
! 624: void *oldp;
! 625: size_t *oldlenp;
! 626: void *newp;
! 627: size_t newlen;
! 628: struct proc *p;
! 629: {
! 630: /* all sysctl names at this level are terminal */
! 631: if (namelen != 1)
! 632: return ENOTDIR;
! 633: switch (name[0]) {
! 634: default:
! 635: return EOPNOTSUPP;
! 636: }
! 637: }
! 638:
! 639: void
! 640: dumpsys()
! 641: {
! 642: printf("dumpsys: TBD\n");
! 643: }
! 644:
! 645: volatile int cpl, ipending, astpending;
! 646: int imask[IPL_NUM];
! 647: int netisr;
! 648:
! 649: /*
! 650: * Soft networking interrupts.
! 651: */
! 652: void
! 653: softnet(isr)
! 654: int isr;
! 655: {
! 656: #define DONETISR(flag, func) \
! 657: if (isr & (1 << (flag))) \
! 658: (func)();
! 659:
! 660: #include <net/netisr_dispatch.h>
! 661: #undef DONETISR
! 662: }
! 663:
! 664: int
! 665: lcsplx(ipl)
! 666: int ipl;
! 667: {
! 668: int oldcpl;
! 669:
! 670: oldcpl = cpl;
! 671: splx(ipl);
! 672: return oldcpl;
! 673: }
! 674:
! 675: /*
! 676: * Halt or reboot the machine after syncing/dumping according to howto.
! 677: */
! 678: void
! 679: boot(howto)
! 680: int howto;
! 681: {
! 682: static int syncing;
! 683: static char str[256];
! 684:
! 685: boothowto = howto;
! 686: if (!cold && !(howto & RB_NOSYNC) && !syncing) {
! 687: syncing = 1;
! 688: vfs_shutdown(); /* sync */
! 689:
! 690: /*
! 691: * If we've been adjusting the clock, the todr
! 692: * will be out of synch; adjust it now unless
! 693: * the system was sitting in ddb.
! 694: */
! 695: if ((howto & RB_TIMEBAD) == 0) {
! 696: resettodr();
! 697: } else {
! 698: printf("WARNING: not updating battery clock\n");
! 699: }
! 700: }
! 701: splhigh();
! 702: if (howto & RB_HALT) {
! 703: doshutdownhooks();
! 704: printf("halted\n\n");
! 705: (fw->exit)();
! 706: }
! 707: if (!cold && (howto & RB_DUMP))
! 708: dumpsys();
! 709: doshutdownhooks();
! 710: printf("rebooting\n\n");
! 711:
! 712: (fw->boot)(str);
! 713: for (;;) ; /* spinning */
! 714: }
! 715:
! 716: /*
! 717: * Get Ethernet address for the onboard ethernet chip.
! 718: */
! 719: void
! 720: myetheraddr(cp)
! 721: u_char *cp;
! 722: {
! 723: struct mvmeprom_brdid brdid;
! 724:
! 725: mvmeprom_brdid(&brdid);
! 726: bcopy(&brdid.etheraddr, cp, 6);
! 727: }
! 728:
! 729: typedef void (void_f) (void);
! 730: void_f *pending_int_f = NULL;
! 731:
! 732: /* call the bus/interrupt controller specific pending interrupt handler
! 733: * would be nice if the offlevel interrupt code was handled here
! 734: * instead of being in each of the specific handler code
! 735: */
! 736: void
! 737: do_pending_int()
! 738: {
! 739: if (pending_int_f != NULL) {
! 740: (*pending_int_f)();
! 741: }
! 742: }
! 743:
! 744: /*
! 745: * one attempt at interrupt stuff..
! 746: *
! 747: */
! 748: #include <dev/pci/pcivar.h>
! 749: typedef void *(intr_establish_t)(void *, pci_intr_handle_t,
! 750: int, int, int (*func)(void *), void *, char *);
! 751: typedef void (intr_disestablish_t)(void *, void *);
! 752:
! 753: int ppc_configed_intr_cnt = 0;
! 754: struct intrhand ppc_configed_intr[MAX_PRECONF_INTR];
! 755:
! 756: void *ppc_intr_establish(void *, pci_intr_handle_t, int, int, int (*)(void *),
! 757: void *, char *);
! 758: void ppc_intr_setup(intr_establish_t *, intr_disestablish_t *);
! 759: void ppc_intr_enable(int);
! 760: int ppc_intr_disable(void);
! 761:
! 762: void *
! 763: ppc_intr_establish(lcv, ih, type, level, func, arg, name)
! 764: void *lcv;
! 765: pci_intr_handle_t ih;
! 766: int type;
! 767: int level;
! 768: int (*func)(void *);
! 769: void *arg;
! 770: char *name;
! 771: {
! 772: if (ppc_configed_intr_cnt < MAX_PRECONF_INTR) {
! 773: ppc_configed_intr[ppc_configed_intr_cnt].ih_fun = func;
! 774: ppc_configed_intr[ppc_configed_intr_cnt].ih_arg = arg;
! 775: ppc_configed_intr[ppc_configed_intr_cnt].ih_level = level;
! 776: ppc_configed_intr[ppc_configed_intr_cnt].ih_irq = ih;
! 777: ppc_configed_intr[ppc_configed_intr_cnt].ih_what = name;
! 778: ppc_configed_intr_cnt++;
! 779: } else {
! 780: panic("ppc_intr_establish called before interrupt controller"
! 781: " configured: driver %s has too many interrupts", name);
! 782: }
! 783: /* disestablish is going to be tricky to supported for these :-) */
! 784: return (void *)ppc_configed_intr_cnt;
! 785: }
! 786:
! 787: intr_establish_t *intr_establish_func = ppc_intr_establish;
! 788: intr_disestablish_t *intr_disestablish_func;
! 789:
! 790: void
! 791: ppc_intr_setup(intr_establish_t *establish, intr_disestablish_t *disestablish)
! 792: {
! 793: intr_establish_func = establish;
! 794: intr_disestablish_func = disestablish;
! 795: }
! 796:
! 797: vaddr_t ppc_kvm_stolen = VM_KERN_ADDRESS_SIZE;
! 798:
! 799: void *
! 800: mapiodev(pa, len)
! 801: paddr_t pa;
! 802: psize_t len;
! 803: {
! 804: paddr_t spa;
! 805: vaddr_t vaddr, va;
! 806: int off;
! 807: int size;
! 808:
! 809: spa = trunc_page(pa);
! 810: off = pa - spa;
! 811: size = round_page(off+len);
! 812:
! 813: if (ppc_malloc_ok == 0) {
! 814: /* need to steal vm space before kernel vm is initialized */
! 815: va = VM_MIN_KERNEL_ADDRESS + ppc_kvm_stolen;
! 816: ppc_kvm_stolen += size;
! 817: if (ppc_kvm_stolen > PPC_SEGMENT_LENGTH) {
! 818: panic("ppc_kvm_stolen: out of space");
! 819: }
! 820: } else {
! 821: va = uvm_km_valloc_wait(phys_map, size);
! 822: }
! 823:
! 824: if (va == 0)
! 825: return NULL;
! 826:
! 827: for (vaddr = va; size > 0; size -= PAGE_SIZE) {
! 828: pmap_kenter_cache(vaddr, spa,
! 829: VM_PROT_READ | VM_PROT_WRITE, PMAP_CACHE_DEFAULT);
! 830: spa += PAGE_SIZE;
! 831: vaddr += PAGE_SIZE;
! 832: }
! 833: return (void *) (va+off);
! 834: }
! 835: void
! 836: unmapiodev(kva, p_size)
! 837: void *kva;
! 838: psize_t p_size;
! 839: {
! 840: vaddr_t vaddr;
! 841: int size;
! 842:
! 843: size = p_size;
! 844:
! 845: vaddr = trunc_page((vaddr_t)kva);
! 846:
! 847: uvm_km_free_wakeup(phys_map, vaddr, size);
! 848:
! 849: for (; size > 0; size -= PAGE_SIZE) {
! 850: pmap_remove(pmap_kernel(), vaddr, vaddr+PAGE_SIZE-1);
! 851: vaddr += PAGE_SIZE;
! 852: }
! 853: pmap_update(pmap_kernel());
! 854: }
! 855:
! 856: /* bcopy(), error on fault */
! 857: int
! 858: kcopy(from, to, size)
! 859: const void *from;
! 860: void *to;
! 861: size_t size;
! 862: {
! 863: faultbuf env;
! 864: void *oldh = curproc->p_addr->u_pcb.pcb_onfault;
! 865:
! 866: if (setfault(&env)) {
! 867: curproc->p_addr->u_pcb.pcb_onfault = oldh;
! 868: return EFAULT;
! 869: }
! 870: bcopy(from, to, size);
! 871: curproc->p_addr->u_pcb.pcb_onfault = oldh;
! 872:
! 873: return 0;
! 874: }
CVSweb