📄 machdep.c
字号:
p->p_sigmask &= ~sig; psignal(p, SIGILL); return; } /* * Build the argument list for the signal handler. */ regs[A0] = sig; regs[A1] = code; regs[A2] = (int)&fp->sf_sc; regs[A3] = (int)catcher; regs[PC] = (int)catcher; regs[SP] = (int)fp; /* * Signal trampoline code is at base of user stack. */ regs[RA] = (int)PS_STRINGS - (esigcode - sigcode);#ifdef DEBUG if ((sigdebug & SDB_FOLLOW) || (sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): sig %d returns\n", p->p_pid, sig);#endif}/* * System call to cleanup state after a signal * has been taken. Reset signal mask and * stack state from context left by sendsig (above). * Return to previous pc and psl as specified by * context left by sendsig. Check carefully to * make sure that the user has not modified the * psl to gain improper priviledges or to cause * a machine fault. */struct sigreturn_args { struct sigcontext *sigcntxp;};/* ARGSUSED */sigreturn(p, uap, retval) struct proc *p; struct sigreturn_args *uap; int *retval;{ register struct sigcontext *scp; register int *regs; struct sigcontext ksc; int error; scp = uap->sigcntxp;#ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);#endif regs = p->p_md.md_regs; /* * Test and fetch the context structure. * We grab it all at once for speed. */ error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof(ksc)); if (error || ksc.sc_regs[ZERO] != 0xACEDBADE) {#ifdef DEBUG if (!(sigdebug & SDB_FOLLOW)) printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp); printf(" old sp %x ra %x pc %x\n", regs[SP], regs[RA], regs[PC]); printf(" new sp %x ra %x pc %x err %d z %x\n", ksc.sc_regs[SP], ksc.sc_regs[RA], ksc.sc_regs[PC], error, ksc.sc_regs[ZERO]);#endif return (EINVAL); } scp = &ksc; /* * Restore the user supplied information */ if (scp->sc_onstack & 01) p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK; else p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK; p->p_sigmask = scp->sc_mask &~ sigcantmask; regs[PC] = scp->sc_pc; bcopy((caddr_t)&scp->sc_regs[1], (caddr_t)®s[1], sizeof(scp->sc_regs) - sizeof(int)); if (scp->sc_fpused) bcopy((caddr_t)scp->sc_fpregs, (caddr_t)&p->p_md.md_regs[F0], sizeof(scp->sc_fpregs)); return (EJUSTRETURN);}int waittime = -1;boot(howto) register int howto;{ /* take a snap shot before clobbering any registers */ if (curproc) savectx(curproc->p_addr, 0);#ifdef DEBUG if (panicstr) stacktrace();#endif boothowto = howto; if ((howto & RB_NOSYNC) == 0 && waittime < 0) { register struct buf *bp; int iter, nbusy; waittime = 0; (void) spl0(); printf("syncing disks... "); /* * Release vnodes held by texts before sync. */ if (panicstr == 0) vnode_pager_umount(NULL);#ifdef notdef#include "fd.h"#if NFD > 0 fdshutdown();#endif#endif sync(&proc0, (void *)NULL, (int *)NULL); for (iter = 0; iter < 20; iter++) { nbusy = 0; for (bp = &buf[nbuf]; --bp >= buf; ) if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY) nbusy++; if (nbusy == 0) break; printf("%d ", nbusy); DELAY(40000 * iter); } if (nbusy) printf("giving up\n"); else printf("done\n"); /* * If we've been adjusting the clock, the todr * will be out of synch; adjust it now. */ resettodr(); } (void) splhigh(); /* extreme priority */ if (callv != &callvec) { if (howto & RB_HALT) (*callv->rex)('h'); else { if (howto & RB_DUMP) dumpsys(); (*callv->rex)('b'); } } else if (howto & RB_HALT) { volatile void (*f)() = (volatile void (*)())DEC_PROM_REINIT; (*f)(); /* jump back to prom monitor */ } else { volatile void (*f)() = (volatile void (*)())DEC_PROM_AUTOBOOT; if (howto & RB_DUMP) dumpsys(); (*f)(); /* jump back to prom monitor and do 'auto' cmd */ } /*NOTREACHED*/}int dumpmag = (int)0x8fca0101; /* magic number for savecore */int dumpsize = 0; /* also for savecore */long dumplo = 0;dumpconf(){ int nblks; dumpsize = physmem; if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) { nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); if (dumpsize > btoc(dbtob(nblks - dumplo))) dumpsize = btoc(dbtob(nblks - dumplo)); else if (dumplo == 0) dumplo = nblks - btodb(ctob(physmem)); } /* * Don't dump on the first CLBYTES (why CLBYTES?) * in case the dump device includes a disk label. */ if (dumplo < btodb(CLBYTES)) dumplo = btodb(CLBYTES);}/* * Doadump comes here after turning off memory management and * getting on the dump stack, either when called above, or by * the auto-restart code. */dumpsys(){ int error; msgbufmapped = 0; if (dumpdev == NODEV) return; /* * For dumps during autoconfiguration, * if dump device has already configured... */ if (dumpsize == 0) dumpconf(); if (dumplo < 0) return; printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo); printf("dump "); switch (error = (*bdevsw[major(dumpdev)].d_dump)(dumpdev)) { case ENXIO: printf("device bad\n"); break; case EFAULT: printf("device not ready\n"); break; case EINVAL: printf("area improper\n"); break; case EIO: printf("i/o error\n"); break; default: printf("error %d\n", error); break; case 0: printf("succeeded\n"); }}/* * Return the best possible estimate of the time in the timeval * to which tvp points. Unfortunately, we can't read the hardware registers. * We guarantee that the time will be greater than the value obtained by a * previous call. */microtime(tvp) register struct timeval *tvp;{ int s = splclock(); static struct timeval lasttime; *tvp = time;#ifdef notdef tvp->tv_usec += clkread(); while (tvp->tv_usec > 1000000) { tvp->tv_sec++; tvp->tv_usec -= 1000000; }#endif if (tvp->tv_sec == lasttime.tv_sec && tvp->tv_usec <= lasttime.tv_usec && (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) { tvp->tv_sec++; tvp->tv_usec -= 1000000; } lasttime = *tvp; splx(s);}initcpu(){ register volatile struct chiptime *c; int i; /* disable clock interrupts (until startrtclock()) */ c = Mach_clock_addr; c->regb = REGB_DATA_MODE | REGB_HOURS_FORMAT; i = c->regc; spl0(); /* safe to turn interrupts on now */ return (i);}/* * Convert an ASCII string into an integer. */intatoi(s) char *s;{ int c; unsigned base = 10, d; int neg = 0, val = 0; if (s == 0 || (c = *s++) == 0) goto out; /* skip spaces if any */ while (c == ' ' || c == '\t') c = *s++; /* parse sign, allow more than one (compat) */ while (c == '-') { neg = !neg; c = *s++; } /* parse base specification, if any */ if (c == '0') { c = *s++; switch (c) { case 'X': case 'x': base = 16; break; case 'B': case 'b': base = 2; break; default: base = 8; } } /* parse number proper */ for (;;) { if (c >= '0' && c <= '9') d = c - '0'; else if (c >= 'a' && c <= 'z') d = c - 'a' + 10; else if (c >= 'A' && c <= 'Z') d = c - 'A' + 10; else break; val *= base; val += d; c = *s++; } if (neg) val = -val;out: return val; }/* * Fill in the pmax addresses by hand. */static struct pmax_address { char *pmax_name; char *pmax_addr; int pmax_pri;} pmax_addresses[] = { { "pm", (char *)MACH_PHYS_TO_CACHED(KN01_PHYS_FBUF_START), 3 }, { "dc", (char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_DZ), 2 }, { "le", (char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_LANCE), 1 }, { "sii",(char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_SII), 0 }, { (char *)0, },};voidpmax_slot_hand_fill(){ register struct pmax_ctlr *cp; register struct driver *drp; register struct pmax_address *pmap; /* * Find the device driver entry and fill in the address. */ for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) { for (pmap = pmax_addresses; pmap->pmax_name; pmap++) { if (strcmp(drp->d_name, pmap->pmax_name)) continue; if (cp->pmax_addr == (char *)QUES) { cp->pmax_addr = pmap->pmax_addr; cp->pmax_pri = pmap->pmax_pri; continue; } } }}#ifdef DS5000/* * Mach Operating System * Copyright (c) 1991,1990,1989 Carnegie Mellon University * All Rights Reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. *//* * Driver map: associates a device driver to an option type. * Drivers name are (arbitrarily) defined in each driver and * used in the various config tables. */struct drivers_map { char module_name[TC_ROM_LLEN]; /* from ROM, literally! */ char *driver_name; /* in bus_??_init[] tables */} tc_drivers_map[] = { { "KN02 ", "dc"}, /* (*) 3max system board (with DC) */ { "PMAD-AA ", "le"}, /* Ether */ { "PMAZ-AA ", "asc"}, /* SCSI */ { "PMAG-AA ", "mfb"}, /* Mono Frame Buffer */ { "PMAG-BA ", "cfb"}, /* Color Frame Buffer */ { "PMAG-CA ", "ga"}, /* 2D graphic board */ { "PMAG-DA ", "gq"}, /* 3D graphic board (LM) */ { "PMAG-FA ", "gq"}, /* 3D graphic board (HE) */ { "PMAG-DV ", "xcfb"}, /* (*) maxine Color Frame Buffer */ { "Z8530 ", "scc"}, /* (*) 3min/maxine serial lines */ { "ASIC ", "asic"}, /* (*) 3min/maxine DMA controller */ { "XINE-FDC", "fdc"}, /* (*) maxine floppy controller */ { "DTOP ", "dtop"}, /* (*) maxine desktop bus */ { "AMD79c30", "isdn"}, /* (*) maxine ISDN chip */ { "XINE-FRC", "frc"}, /* (*) maxine free-running counter */ { "", 0} /* list end */};/* * Identify an option on the TC. Looks at the mandatory * info in the option's ROM and checks it. */#ifdef DEBUGint tc_verbose = 0;#endifstatic inttc_identify_option(addr, slot, complain) tc_rommap_t *addr; tc_option_t *slot; int complain;{ register int i; unsigned char width; char firmwr[TC_ROM_LLEN+1], vendor[TC_ROM_LLEN+1], module[TC_ROM_LLEN+1], host_type[TC_ROM_SLEN+1]; /* * We do not really use the 'width' info, but take advantage * of the restriction that the spec impose on the portion * of the ROM that maps between +0x3e0 and +0x470, which * is the only piece we need to look at. */ width = addr->rom_width.value; switch (width) { case 1: case 2: case 4: break; default:#ifdef DEBUG if (tc_verbose && complain) printf("%s (x%x) at x%x\n", "Invalid ROM width", width, addr);#endif return (0); } if (addr->rom_stride.value != 4) {#ifdef DEBUG if (tc_verbose && complain) printf("%s (x%x) at x%x\n", "Invalid ROM stride", addr->rom_stride.value, addr);#endif return (0); } if ((addr->test_data[0] != 0x55) || (addr->test_data[4] != 0x00) || (addr->test_data[8] != 0xaa) || (addr->test_data[12] != 0xff)) {#ifdef DEBUG if (tc_verbose && complain) printf("%s x%x\n", "Test pattern failed, option at", addr);#endif return (0); } for (i = 0; i < TC_ROM_LLEN; i++) { firmwr[i] = addr->firmware_rev[i].value; vendor[i] = addr->vendor_name[i].value; module[i] = addr->module_name[i].value; if (i >= TC_ROM_SLEN) continue; host_type[i] = addr->host_firmware_type[i].value; } firmwr[TC_ROM_LLEN] = vendor[TC_ROM_LLEN] = module[TC_ROM_LLEN] = host_type[TC_ROM_SLEN] = '\0';#ifdef DEBUG if (tc_verbose) printf("%s %s '%s' at 0x%x\n %s %s %s '%s'\n %s %d %s %d %s\n", "Found a", vendor, module, addr, "Firmware rev.", firmwr, "diagnostics for a", host_type, "ROM size is", addr->rom_size.value << 3, "Kbytes, uses", addr->slot_size.value, "TC slot(s)");#endif bcopy(module, slot->module_name, TC_ROM_LLEN); bcopy(vendor, slot->module_id, TC_ROM_LLEN); bcopy(firmwr, &slot->module_id[TC_ROM_LLEN], TC_ROM_LLEN); slot->slot_size = addr->slot_size.value; slot->rom_width = width; return (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -