📄 machdep.c
字号:
USER_REG(EF_EPC) = scp->sc_pc; USER_REG(EF_MDLO) = scp->sc_mdlo; USER_REG(EF_MDHI) = scp->sc_mdhi; for (urp = &USER_REG(EF_AT), srp = &scp->sc_regs[R_AT]; urp <= &USER_REG(EF_RA); urp++, srp++) *urp = *srp; if (scp->sc_ownedfp) { checkfp(u.u_procp, 1); /* toss current fp contents */ for (frp = u.u_pcb.pcb_fpregs, srp = &scp->sc_fpregs[0]; frp < &u.u_pcb.pcb_fpregs[32]; frp++, srp++) *frp = *srp; u.u_pcb.pcb_fpc_csr = scp->sc_fpc_csr & ~FPCSR_EXCEPTIONS; }}physstrat(bp, strat, prio) struct buf *bp; int (*strat)(), prio;{ int s; int count = bp->b_bcount; caddr_t addr = bp->b_un.b_addr; (*strat)(bp); /* pageout daemon doesn't wait for pushed pages */ if (bp->b_flags & (B_DIRTY|B_RAWASYNC)) return; s = splclock(); while ((bp->b_flags & B_DONE) == 0) sleep((caddr_t)bp, prio); splx(s);#ifdef oldmips if (bp->b_flags & B_READ) bufflush(bp); /* do this if you do dma....rr */#endif oldmips}int waittime = -1;int shutting_down = 0;boot(paniced, arghowto)int paniced, arghowto;{ register int howto; /* r11 == how to boot */ register int devtype; /* r10 == major of root dev */ register struct mount *mp; register struct gnode *gp; register struct pte *ptep; register int s; struct gnode *rgp; extern struct gnode *fref(); extern struct gnode *acctp; extern struct gnode *savacctp; extern struct cred *acctcred; extern struct lock_t lk_acct;#ifdef lint howto = 0; devtype = 0; printf ("howto %d, devtype %d\n", arghowto, devtype);#endif (void) splextreme(); howto = arghowto; rundown++; shutting_down++; if ((howto & RB_NOSYNC) == 0 && waittime < 0 && bfreelist[0].b_forw) { /* * If accounting is on, turn it off. This allows the usr * filesystem to be umounted cleanly. */ smp_lock(&lk_acct, LK_RETRY); if (savacctp) { acctp = savacctp; savacctp = NULL; } if (gp = acctp) { gfs_lock(gp); if (acctp != NULL) { acctp = NULL; GSYNCG(gp, acctcred); crfree(acctcred); acctcred = NULL; gput(gp); } else gfs_unlock(gp); } smp_unlock(&lk_acct); (void) splnet(); waittime = 0; gfs_gupdat(NODEV); if (paniced != RB_PANIC) { update(); /* flush dirty blocks */ /* unmount all but root fs */ /* include paranoid checks for active unmounts */ /* and preclude new unmounts */ for (mp = &mount[NMOUNT - 1]; mp > mount; mp--) { smp_lock(&mp->m_lk, LK_RETRY); if ((mp->m_flgs & MTE_DONE) && !(mp->m_flgs & MTE_UMOUNT)) { mp->m_flgs |= MTE_UMOUNT; smp_unlock(&mp->m_lk); GUMOUNT(mp, 1); } else { smp_unlock(&mp->m_lk); } } } printf ("syncing disks... "); (void) splhigh(); bflush (NODEV, (struct gnode *) 0, 1); printf ("done\n"); /* * If we've been adjusting the clock, the todr * will be out of synch; adjust it now. */ resettodr(); } (void) splextreme(); devtype = major (rootdev); (void) save(); if (howto & RB_HALT) { printf("halting.... (transferring to monitor)\n\n"); if(console_magic != REX_MAGIC) prom_restart(); /* always enters command mode */ else { rex_rex('h'); } /* doesn't return */ } else { if (paniced == RB_PANIC) { dumpsys(); if(console_magic != REX_MAGIC) prom_reboot(); /* follows $bootmode */ else { rex_rex('r'); } /* doesn't return */ } } printf("rebooting.... (transferring to monitor)\n\n"); if(console_magic != REX_MAGIC) prom_autoboot(); /* always reboots */ else { rex_rex('b'); } /* doesn't return */ for (;;) /* chicken */ ;}ovbcopy(from,to,len)register char *from,*to;register int len;{ if (from < to) { from += len; to += len; while(len--) *--to = *--from; } else { while(len--) *to++ = *from++; }}char boottype[10];struct netblk netblk;/* * called from init_main to see if a network boot has occurred. If so, * available information is read into a local copy of the netblk * structure. As per original design the changing of 'roottype' is what * triggers init_main to assume a diskless network environment. */netbootchk(){ extern struct netblk *netblk_ptr; extern int roottype; extern int swaptype; extern int dumptype; extern int swapsize; extern char *bootdev; extern int console_magic; extern char **ub_argv; extern int ub_argc; char *bootstring; int i; /* * Note: network boot can be for diskless or Standalone * ULTRIX. The caller (init_main.c) checks roottype to * sense the difference. */ boottype[0] = '\0'; if(console_magic != REX_MAGIC) bootdev = (char *)prom_getenv("boot"); else { for(i=1;i<ub_argc;i++) { if((ub_argv[i][0] != '-') && (ub_argv[i][0] != NULL)) if(ub_argv[i][1] == '/') bootdev = (char *)ub_argv[i]; } } i=0; while(bootdev[i] != NULL) { /* Save for network crashing */ netdevice[i] = bootdev[i]; i++; } netdevice[i] = bootdev[i]; if ((!strncmp(bootdev, "mop", 3)) || (!strncmp(bootdev, "tftp", 4)) || (!strncmp(&bootdev[2], "mop", 3)) || (!strncmp(&bootdev[2], "tftp", 4))) { int i; char *j; /* * Take a picture of the netblk structure in case * it gets tromped on by someone other than the * kernel. */ bcopy((char *)NETBLK_LDADDR, (char *)&netblk, sizeof (struct netblk)); /* * Clear out that which was just copied so it isn't * hanging around for a subsequent boot. This will * guarantee that NETBLK_LDADDR points to real data * pertaining to this boot. */ j = (char *)NETBLK_LDADDR; for (i = 0; i < sizeof (struct netblk); i++) j[i] = 0; netblk_ptr = &netblk; switch (cpu) { case DS_5000: case DS_5000_100: if (console_magic != REX_MAGIC) { /* * Walk the TURBOchannel looking for the nth * instance of a LANCE or DEFZA. */ if ((bootdev[4] > '0') && (bootdev[4] <= '3')) { int k, unit = bootdev[4] - '0'; extern struct tc_slot tc_slot[]; for (k = 0; k < 3; k++) { if (!strcmp(tc_slot[k].devname,"ln")) if (--unit == 0) { bcopy("ln",boottype,2); boottype[2] = tc_slot[k].unit+'0'; boottype[3] = '\0'; break; } if (!strcmp(tc_slot[k].devname,"fza")) if (--unit == 0) { bcopy("fza",boottype,3); boottype[3] = tc_slot[k].unit+'0'; boottype[4] = '\0'; break; } } } else { /* * For unit = 0 and default, use "ln0" */ bcopy("ln0",boottype,3); boottype[3] = '\0'; } } else { /* New TURBOchannel console */ int k,j; extern struct tc_slot tc_slot[]; /* * Walk the TURBOchannel looking for the nth * instance of a LANCE or DEFZA. */ j=bootdev[0]-0x30; for(k = 0; k <= 6; k++) { if(tc_slot[k].slot == j) { if (!strcmp(tc_slot[k].devname,"ln")) { bcopy("ln",boottype,2); boottype[2] = tc_slot[k].unit+'0'; boottype[3] = '\0'; break; } if (!strcmp(tc_slot[k].devname,"fza")) { bcopy("fza",boottype,3); boottype[3] = tc_slot[k].unit+'0'; boottype[4] = '\0'; break; } } } /* END FOR */ } /* END ELSE */ break; case DS_5500: bcopy("ne0",boottype,3); boottype[3] = '\0'; break; case DS_3100: case DS_5100: case DS_5400: default: bcopy("ln0",boottype,3); boottype[3] = '\0'; break; } if (netblk_ptr->rootfs == GT_NFS) { roottype= (int) netblk_ptr->rootfs; swaptype= (int) netblk_ptr->swapfs; swapsize= ((int) netblk_ptr->swapsz) * 1024; if (netblk_ptr->dmpflg != -1) dumptype= ((int) netblk_ptr->dmpflg) * 1024; } }}/* * Call system specific configuration routine. */configure(){ if ((*(cpup->config))() < 0) panic("No configuration routine configured\n");}/* * Delay for n microseconds * Call through the system switch to specific delay routine. */microdelay(usecs) int usecs;{ (*(cpup->microdelay))(usecs);}read_todclk(){ extern int nocpu(); if (cpup->readtodr == nocpu) panic("No read TOD routine configured\n"); else return((*(cpup->readtodr))());}write_todclk(){ extern int nocpu(); if (cpup->writetodr == nocpu) panic("No write TOD routine configured\n"); else return((*(cpup->writetodr))());}/* * Wait until the write buffer of the processor we are on is empty. * In "critical path code", don't check return status. */wbflush(){ (*(cpup->wbflush))();}/* * Machine dependent badaddr. * * On machines such as on the BI, access to NXM in BI does not * necessarily cause error interrupts or exceptions. The only * error indication may be the setting of error bits in error registers. */badaddr(addr,len)caddr_t addr;int len;{ int status, s; extern int cold; /* booting in progress */ if (cold) status = (*(cpup->badaddr))(addr,len); else { s = splextreme(); /* Disable interrupts */ switch(cpu) { case DS_3100: case DS_5000: case DS_5000_100: case DS_5100: case DS_5400: case DS_5500: case DS_5800: default: status = (*(cpup->badaddr))(addr,len); break; } splx(s); /* Restore interrupts */ } return(status);}release_uarea_noreturn() { CURRENT_CPUDATA->cpu_exitproc = u.u_procp; (void)splclock(); smp_lock(&lk_rq,LK_RETRY); swtch();}startrtclock(){ if ((*(cpup->startclocks))() < 0) panic("No start clock routine configured\n");}spl5() { return(splbio());}/* * Acknowledge clock interrupt. * In "critical path code", don't check return status. */ackrtclock(){ (*(cpup->ackclock))();}stopclocks(){ if ((*(cpup->stopclocks))() < 0) panic("No stop clock routine configured\n");}/* * Flush the system caches. * In "critical path code", don't check return status. */flush_cache(){/* A bug in the R3000 that causes the cache isolate to fail if the write buffers * are full is worked around via wbflush. */ int s; s = splextreme(); (*(cpup->wbflush))(); (*(cpup->flush_cache))(); splx(s);}clean_icache (addr,len){/* A bug in the R3000 that causes the cache isolate to fail if the write buffers * are full is worked around via wbflush. */ int s; s = splextreme(); (*(cpup->wbflush))(); (*(cpup->clean_icache))(addr,len); splx(s);}clean_dcache (addr,len){/* A bug in the R3000 that causes the cache isolate to fail if the write buffers * are full is worked around via wbflush. */ int s; s = splextreme(); (*(cpup->wbflush))(); (*(cpup->clean_dcache))(addr,len); splx(s);}page_iflush (addr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -