void w_power(Ether* ether, int on) { Ctlr *ctlr; ctlr = (Ctlr*) ether->ctlr; ilock(ctlr); iprint("w_power %d\n", on); if(on){ if((ctlr->state & Power) == 0){ if (wavelanreset(ether, ctlr) < 0){ iprint("w_power: reset failed\n"); iunlock(ctlr); w_detach(ether); free(ctlr); return; } if(ctlr->state & Attached) w_enable(ether); ctlr->state |= Power; } }else{ if(ctlr->state & Power){ if(ctlr->state & Attached) w_intdis(ctlr); ctlr->state &= ~Power; } } iunlock(ctlr); }
/* * Called when scheduler has decided to run proc p. * Prepare to run proc p. */ void mmuswitch(Proc *p) { /* * Switch the address space, but only if it's not the * one we were just in. Also, kprocs don't count -- * only the guys on cpu0 do. */ if(p->kp) return; if(tracemmu) iprint("mmuswitch %ld %s\n", p->pid, p->text); if(p->pmmu.us && p->pmmu.us->p == p) { if(tracemmu) iprint("---------- %ld %s [%d]\n", p->pid, p->text, p->pmmu.us - uspace); usespace(p->pmmu.us); if(!p->newtlb && !m->flushmmu) { usespace(p->pmmu.us); return; } mmapflush(p->pmmu.us); p->newtlb = 0; return; } if(p->pmmu.us == nil) getspace(p); else takespace(p, p->pmmu.us); if(tracemmu) iprint("========== %ld %s [%d]\n", p->pid, p->text, p->pmmu.us - uspace); }
void dumpregs(Ureg* ureg) { vlong mca, mct; dumpregs2(ureg); /* * Processor control registers. * If machine check exception, time stamp counter, page size extensions * or enhanced virtual 8086 mode extensions are supported, there is a * CR4. If there is a CR4 and machine check extensions, read the machine * check address and machine check type registers if RDMSR supported. */ iprint(" CR0 %8.8lux CR2 %8.8lux CR3 %8.8lux", getcr0(), getcr2(), getcr3()); if(m->cpuiddx & 0x9A){ iprint(" CR4 %8.8lux", getcr4()); if((m->cpuiddx & 0xA0) == 0xA0){ rdmsr(0x00, &mca); rdmsr(0x01, &mct); iprint("\n MCA %8.8llux MCT %8.8llux", mca, mct); } } iprint("\n ur %#p up %#p\n", ureg, up); }
void clockinit(void) { long x; m->delayloop = m->cpuhz/1000; /* initial estimate */ do { x = gettbl(); delay(10); x = gettbl() - x; } while(x < 0); /* * fix count */ m->delayloop = ((vlong)m->delayloop*(10*(vlong)m->clockgen/1000))/(x*Timebase); if((int)m->delayloop <= 0) m->delayloop = 20000; x = (m->clockgen/Timebase)/HZ; putpit(x); iprint("pit value=%.8lux [%lud]\n", x, x); puttsr(~0); puttcr(Pie|Are); iprint("boot=%.8lux epctl=%.8lux pllmr0=%.8lux pllmr1=%.8lux ucr=%.8lux\n", getdcr(Boot), getdcr(Epctl), getdcr(Pllmr0), getdcr(Pllmr1), getdcr(Ucr)); }
/* tear down the identity map we created in assembly. ONLY do this after all the * APs have started up (and you know they've done so. But you must do it BEFORE * you create address spaces for procs, i.e. userinit() */ static void teardownidmap(Mach *m) { int i; uintptr_t va = 0; PTE *p; /* loop on the level 2 because we should not assume we know * how many there are But stop after 1G no matter what, and * report if there were that many, as that is odd. */ for(i = 0; i < 512; i++, va += BIGPGSZ) { if (mmuwalk(UINT2PTR(m->pml4->va), va, 1, &p, nil) != 1) break; if (! *p) break; iprint("teardown: va %p, pte %p\n", (void *)va, p); *p = 0; } iprint("Teardown: zapped %d PML1 entries\n", i); for(i = 2; i < 4; i++) { if (mmuwalk(UINT2PTR(m->pml4->va), 0, i, &p, nil) != i) { iprint("weird; 0 not mapped at %d\n", i); continue; } iprint("teardown: zap %p at level %d\n", p, i); if (p) *p = 0; } }
static int chanintr(Ctlr *ctlr, int n) { Hostchan *hc; int i; hc = &ctlr->regs->hchan[n]; if(ctlr->debugchan & (1<<n)) clog(nil, hc); if((hc->hcsplt & Spltena) == 0) return 0; i = hc->hcint; if(i == (Chhltd|Ack)){ hc->hcsplt |= Compsplt; ctlr->splitretry = 0; }else if(i == (Chhltd|Nyet)){ if(++ctlr->splitretry >= 3) return 0; }else return 0; if(hc->hcchar & Chen){ iprint("hcchar %8.8ux hcint %8.8ux", hc->hcchar, hc->hcint); hc->hcchar |= Chen | Chdis; while(hc->hcchar&Chen) ; iprint(" %8.8ux\n", hc->hcint); } hc->hcint = i; if(ctlr->regs->hfnum & 1) hc->hcchar &= ~Oddfrm; else hc->hcchar |= Oddfrm; hc->hcchar = (hc->hcchar &~ Chdis) | Chen; return 1; }
/* * Start a keypress monitoring thread and reopen switch * to a new silent TTY. * * When called with UPD_SILENT, mtx_tty should be held. */ void switchmon_start(int update, int stty) { /* Has the silent TTY changed? */ if (update & UPD_SILENT) { if (config.tty_s != stty) { vt_silent_cleanup(); fbsplashr_tty_silent_set(stty); } vt_silent_init(); } /* Do we have to start a monitor thread? */ if (update & UPD_MON) { if (fd_evdev != -1) { if (pthread_create(&th_switchmon, NULL, &thf_switch_evdev, NULL)) { iprint(MSG_ERROR, "Evdev monitor thread creation failed.\n"); exit(3); } } else { if (pthread_create(&th_switchmon, NULL, &thf_switch_ttymon, NULL)) { iprint(MSG_ERROR, "TTY monitor thread creation failed.\n"); exit(3); } } } }
/* * Allocate a process-sized mapping with nothing there. * The point is to reserve the space so that * nothing else ends up there later. */ static void* mapzero(void) { int fd, bit32; void *v; void *hint; bit32 = BIT32; hint = HINT; /* First try mmaping /dev/zero. Some OS'es don't allow this. */ if((fd = open("/dev/zero", O_RDONLY)) >= 0) { v = mmap(hint, USTKTOP, PROT_NONE, bit32|MAP_PRIVATE, fd, 0); if(v != MAP_FAILED) { if((uint32_t)(uintptr)v != (uintptr)v) { iprint("mmap returned 64-bit pointer %p\n", v); panic("mmap"); } return v; } } /* Next try an anonymous map. */ v = mmap(hint, USTKTOP, PROT_NONE, bit32|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if(v != MAP_FAILED) { if((uint32_t)(uintptr)v != (uintptr)v) { iprint("mmap returned 64-bit pointer %p\n", v); panic("mmap"); } return v; } return nil; }
int main(int argv, char *argc[]) { info I, J; int N; double *u; if (argv > 1) {sscanf(argc[1],"%d", &N);} else {N = 100;} // if (scanf("%d", &N)) {} else {N = 40;} iinit(&I, N); u = advection(I.N, I.M); compare(u, I.N); residual(u, &I); iprint(I); free(u); N *= 2; iinit(&J, N); u = advection(J.N, J.M); compare(u, J.N); residual(u, &J); iprint(J); free(u); printf("Degree of convergence = %lg\n\n", log(I.S/J.S)/log(I.h/J.h)); return 0; }
static int kirkwoodmii(Ether *ether) { int i; Ctlr *ctlr; MiiPhy *phy; MIIDBG("mii\n"); ctlr = ether->ctlr; if((ctlr->mii = malloc(sizeof(Mii))) == nil) return -1; ctlr->mii->ctlr = ctlr; ctlr->mii->mir = miird; ctlr->mii->miw = miiwr; if(mymii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){ print("#l%d: ether1116: init mii failure\n", ether->ctlrno); free(ctlr->mii); ctlr->mii = nil; return -1; } /* oui 005043 is marvell */ MIIDBG("oui %#X phyno %d\n", phy->oui, phy->phyno); // TODO: does this make sense? shouldn't each phy be initialised? if((ctlr->ether->ctlrno == 0 || hackflavour != Hackdual) && miistatus(ctlr->mii) < 0){ miireset(ctlr->mii); MIIDBG("miireset\n"); if(miiane(ctlr->mii, ~0, 0, ~0) < 0){ iprint("miiane failed\n"); return -1; } MIIDBG("miistatus\n"); miistatus(ctlr->mii); if(miird(ctlr->mii, phy->phyno, Bmsr) & BmsrLs){ for(i = 0; ; i++){ if(i > 600){ iprint("ether1116: autonegotiation failed\n"); break; } if(miird(ctlr->mii, phy->phyno, Bmsr) & BmsrAnc) break; delay(10); } if(miistatus(ctlr->mii) < 0) iprint("miistatus failed\n"); }else{ iprint("ether1116: no link\n"); phy->speed = 10; /* simple default */ } } ether->mbps = phy->speed; MIIDBG("#l%d: kirkwoodmii: fd %d speed %d tfc %d rfc %d\n", ctlr->port, phy->fd, phy->speed, phy->tfc, phy->rfc); MIIDBG("mii done\n"); return 0; }
static void dumpbytes(uchar *bp, long max) { iprint("%#p: ", bp); for (; max > 0; max--) iprint("%02.2ux ", *bp++); iprint("...\n"); }
void dumpcpuclks(void) /* run CPU at full speed */ { Clkrst *clk = (Clkrst *)soc.clkrst; iprint("pllx base %#lux misc %#lux\n", clk->pllxbase, clk->pllxmisc); iprint("plle base %#lux misc %#lux\n", clk->pllebase, clk->pllemisc); iprint("super cclk divider %#lux\n", clk->supcclkdiv); iprint("super sclk divider %#lux\n", clk->supsclkdiv); }
static void dumplockmem(char *tag, Lock *l) { uchar *cp; int i; iprint("%s: ", tag); cp = (uchar*)l; for(i = 0; i < 64; i++) iprint("%2.2ux ", cp[i]); iprint("\n"); }
void powersuspend(void) { extern void suspenditall(void); GpioReg *g; ulong back = 0x43219990; /* check that the stack's right */ ulong pwer, gplr; ulong *rp; int i, s; s = splfhi(); archpowerdown(); /* sets PMGR and PPC appropriately */ if(DEBUG) dumpitall(); blankscreen(1); chandevpower(0); gplr = GPIOREG->gplr; for(i=0; (rp = coreregs[i]) != nil; i++) corestate[i] = *rp; pwer = PMGRREG->pwer; if(pwer == 0) pwer = 1<<0; g = GPIOREG; g->grer &= pwer; /* just the ones archpowerdown requested */ g->gfer &= pwer; g->gedr = g->gedr; RESETREG->rcsr = 0xF; /* reset all status */ minidcflush(); if(DEBUG) iprint("suspenditall...\n"); suspenditall(); /* keep us in suspense */ PMGRREG->pspr = 0; archpowerup(); trapstacks(); /* set output latches before gpdr restored */ GPIOREG->gpsr = gplr; GPIOREG->gpcr = ~gplr; for(i=0; (rp = coreregs[i]) != nil; i++) *rp = corestate[i]; GPIOREG->gedr = GPIOREG->gedr; /* reset GPIO interrupts (should we?) */ PMGRREG->pssr = PSSR_ph; /* cancel peripheral hold */ chandevpower(1); if(back != 0x43219990){ iprint("back %8.8lux\n", back); panic("powersuspend"); } blankscreen(0); if(DEBUG) dumpitall(); splx(s); }
int llfifointr(ulong bit) { ulong len, sts; Ether *ether; RingBuf *rb; static uchar zaddrs[Eaddrlen * 2]; sts = frp->isr; if (sts == 0) return 0; /* not for me */ ether = llether; /* it's important to drain all packets in the rx fifo */ while ((frp->rdfo & Wordcnt) != 0) { assert((frp->rdfo & ~Wordcnt) == 0); len = frp->rlf & Bytecnt; /* read rlf from fifo */ assert((len & ~Bytecnt) == 0); assert(len > 0 && len <= ETHERMAXTU); rb = ðer->rb[ether->ri]; if (rb->owner == Interface) { /* from rx fifo into ring buffer */ fifocpy(rb->pkt, &frp->rdfd, len, Dinc); if (memcmp(rb->pkt, zaddrs, sizeof zaddrs) == 0) { iprint("ether header with all-zero mac " "addresses\n"); continue; } rb->len = len; rb->owner = Host; coherence(); ether->ri = NEXT(ether->ri, ether->nrb); coherence(); } else { discardinpkt(len); /* not too informative during booting */ iprint("llfifo: no buffer for input pkt\n"); } } if (sts & Tc) ether->tbusy = 0; ether->transmit(ether); frp->isr = sts; /* extinguish intr source */ coherence(); intrack(bit); sts &= ~(Tc | Rc); if (sts) iprint("llfifo isr %#lux\n", sts); return 1; }
static int mng_readfile(mng_handle mngh, char *filename) { int fd, len; char *file_data; struct stat sb; mng_anim *mng = mng_get_userdata(mngh); if ((fd = open(filename, O_RDONLY)) < 0) { perror("mng_readfile: open"); return 0; } if (fstat(fd, &sb) == -1) { perror("mng_readfile: stat"); goto close_fail; } mng->len = sb.st_size; if ((mng->data = malloc(mng->len)) == NULL) { iprint(MSG_ERROR, "mng_readfile: Unable to allocate memory for MNG file\n"); goto close_fail; } len = 0; file_data = mng->data; while (len < mng->len) { int ret; int amt = 0x10000; if (mng->len - len < amt) amt = mng->len - len; ret = read(fd, file_data, amt); /* read up to 64KB at a time */ switch (ret) { case -1: perror("mng_readfile: read"); goto close_fail; case 0: iprint(MSG_ERROR, "mng_readfile: Shorter file than expected!\n"); goto close_fail; } file_data += ret; len += ret; } close(fd); return 1; close_fail: close(fd); return 0; }
mng_handle mng_load(char* filename, int *width, int *height) { mng_handle mngh; mng_anim *mng; mng = (mng_anim*)malloc(sizeof(mng_anim)); if (!mng) { iprint(MSG_ERROR, "%s: Unable to allocate memory for MNG data\n", __FUNCTION__); return MNG_NULL; } memset(mng, 0, sizeof(mng_anim)); mngh = mng_initialize(mng, fb_mng_memalloc, fb_mng_memfree, MNG_NULL); if (mngh == MNG_NULL) { iprint(MSG_ERROR, "%s: mng_initialize failed\n", __FUNCTION__); goto freemem_fail; } if (mng_init_callbacks(mngh)) { print_mng_error(mngh, "mng_init_callbacks failed"); goto cleanup_fail; } /* Load the file into memory */ if (!mng_readfile(mngh, filename)) goto cleanup_fail; /* Read and parse the file */ if (mng_read(mngh) != MNG_NOERROR) { /* Do something about it. */ print_mng_error(mngh, "mng_read failed"); goto cleanup_fail; } mng->num_frames = mng_get_totalframes(mngh); *width = mng->canvas_w; *height = mng->canvas_h; return mngh; cleanup_fail: mng_cleanup(&mngh); freemem_fail: free(mng); return MNG_NULL; }
/* * the new kernel is already loaded at address `code' * of size `size' and entry point `entry'. */ void reboot(void *entry, void *code, ulong size) { void (*f)(ulong, ulong, ulong); iprint("starting reboot..."); writeconf(); shutdown(0); /* * should be the only processor running now */ print("shutting down...\n"); delay(200); /* turn off buffered serial console */ serialoq = nil; /* shutdown devices */ chandevshutdown(); /* call off the dog */ clockshutdown(); splhi(); /* setup reboot trampoline function */ f = (void*)REBOOTADDR; memmove(f, rebootcode, sizeof(rebootcode)); cacheuwbinv(); l2cacheuwb(); print("rebooting..."); iprint("entry %#lux code %#lux size %ld\n", PADDR(entry), PADDR(code), size); delay(100); /* wait for uart to quiesce */ /* off we go - never to return */ cacheuwbinv(); l2cacheuwb(); (*f)(PADDR(entry), PADDR(code), size); iprint("loaded kernel returned!\n"); delay(1000); archreboot(); }
void testReadLevelSettingsFile() { iprint(countKeywords()); sput_fail_unless(countKeywords() == 9,"9 Keywords Should Exist in the level settings queue"); initialQueueReader(); //! Removing set up commands sput_fail_unless(countKeywords() == 3,"Valid: 3 Keywords Should Exist in the level settings queue"); sput_fail_unless(getNumberOfPaths() == 1,"Valid: Number of paths that have been set is 1"); sput_fail_unless(getNumOfTowerPositions() == 4,"Valid: Number of tower positions that have been created is 4"); sput_fail_unless(getTowerPositionX(1) == scaleTowerPos(10,SCREEN_WIDTH_GLOBAL,MAX_TOWER_X),"Valid: Tower position 1 x value is as expected after scaling"); sput_fail_unless(getTowerPositionY(1) == scaleTowerPos(500,SCREEN_HEIGHT_GLOBAL,MAX_TOWER_Y),"Valid: Tower position 1 y value is as expected after scaling"); sput_fail_unless(getTotalWaveNo() == 3,"Valid: Total Waves set to three"); setCurrWaveNum(1); sput_fail_unless(returnPropertyValueFromQueue(1,waveID) == 1,"Valid: First keyword has waveID 1"); sput_fail_unless(returnPropertyValueFromQueue(2,waveID) == 2,"Valid: Second keyword has waveID 2"); sput_fail_unless(returnPropertyValueFromQueue(3,waveID) == 3,"Valid: Third keyword has waveID 3"); sput_fail_unless(waveCreatorCommand(getKeywordFromQueue(1)) ==3,"Valid: Three enemy commands should be placed in the queue"); sput_fail_unless(getKeywordTypeFromQueue(3) == wave,"Valid: Third command is queue should be wave"); sput_fail_unless(getKeywordTypeFromQueue(4) == makeEnemy,"Valid: Fourth command is queue should be makeEnemy"); sput_fail_unless(createEnemyCommand(getKeywordFromQueue(4)) == 0,"Invalid:Cooldown for single enemy creation not yet ready"); delayGame(10); sput_fail_unless(createEnemyCommand(getKeywordFromQueue(4)) == 1,"Valid: Cooldown for single enemy creation is ready"); sput_fail_unless(getKeywordTypeFromQueue(7) == delay,"Valid: Seventh Keyword in queue is delay"); sput_fail_unless(setCreateEnemyGroupDelay(returnPropertyValue(getKeywordFromQueue(7),dTime)) == 30, "group delay is 30"); sput_fail_unless(createEnemyCommand(getKeywordFromQueue(4)) == 0,"Invalid: Cooldown for enemy group creation is not ready"); delayGame(30); sput_fail_unless(createEnemyCommand(getKeywordFromQueue(4)) == 1,"Valid: Cooldown for enemy group creation is ready"); sput_fail_unless(waveCreatorCommand(getKeywordFromQueue(2)) ==10,"Valid: Ten enemy commands should be placed in the queue"); sput_fail_unless(createEnemyCommand(getKeywordFromQueue(9)) == 0,"Invalid: Enemy has wave ID for next wave"); setCurrWaveNum(2); delayGame(ENEMYSPAWNCOOLDOWN); sput_fail_unless(createEnemyCommand(getKeywordFromQueue(9)) == 1,"Valid: Enemy has wave ID for current wave"); //levelQueueReader(); }
static void rxreplenish(Ctlr *ctlr) { Rx *r; Block *b; while(ctlr->rxb[ctlr->rxtail] == nil) { b = rxallocb(); if(b == nil) { iprint("#l%d: rxreplenish out of buffers\n", ctlr->ether->ctlrno); break; } ctlr->rxb[ctlr->rxtail] = b; /* set up uncached receive descriptor */ r = &ctlr->rx[ctlr->rxtail]; assert(((uintptr)r & (Descralign - 1)) == 0); r->countsize = ROUNDUP(Rxblklen, 8); r->buf = PADDR(b->rp); coherence(); /* and fire */ r->cs = RCSdmaown | RCSenableintr; coherence(); ctlr->rxtail = NEXT(ctlr->rxtail, Nrx); } }
/* * Expects that only one process can call wakeup for any given Rendez. * We hold both locks to ensure that r->p and p->r remain consistent. * Richard Miller has a better solution that doesn't require both to * be held simultaneously, but I'm a paranoid - presotto. */ Proc* wakeup(Rendez *r) { Proc *p; int s; s = splhi(); lock(r); p = r->p; if(p != nil){ lock(&p->rlock); if(p->state != Wakeme || p->r != r){ iprint("%p %p %d\n", p->r, r, p->state); panic("wakeup: state"); } r->p = nil; p->r = nil; ready(p); unlock(&p->rlock); } unlock(r); splx(s); return p; }
static void wpiinterrupt(Ureg*, void *arg) { u32int isr, fhisr; Ether *edev; Ctlr *ctlr; edev = arg; ctlr = edev->ctlr; ilock(ctlr); csr32w(ctlr, Imr, 0); isr = csr32r(ctlr, Isr); fhisr = csr32r(ctlr, FhIsr); if(isr == 0xffffffff || (isr & 0xfffffff0) == 0xa5a5a5a0){ iunlock(ctlr); return; } if(isr == 0 && fhisr == 0) goto done; csr32w(ctlr, Isr, isr); csr32w(ctlr, FhIsr, fhisr); if((isr & (Iswrx | Ifhrx)) || (fhisr & Ifhrx)) receive(ctlr); if(isr & Ierr){ ctlr->broken = 1; iprint("#l%d: fatal firmware error, lastcmd %ud\n", edev->ctlrno, ctlr->tx[4].lastcmd); } ctlr->wait.m |= isr; if(ctlr->wait.m & ctlr->wait.w) wakeup(&ctlr->wait); done: csr32w(ctlr, Imr, ctlr->ie); iunlock(ctlr); }
static void shutdown(int ispanic) { int ms, once; lock(&active); if(ispanic) active.ispanic = ispanic; else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0) active.ispanic = 0; once = active.machs & (1<<m->machno); active.machs &= ~(1<<m->machno); active.exiting = 1; unlock(&active); if(once) iprint("cpu%d: exiting\n", m->machno); spllo(); for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){ delay(TK2MS(2)); if(active.machs == 0 && consactive() == 0) break; } delay(1000); }
/* * called regularly to avoid calculation overflows */ static void todfix(void) { vlong ticks, diff; uvlong x; ticks = fastticks(nil); diff = ticks - tod.last; if(diff <= tod.hz) return; ilock(&tod); diff = ticks - tod.last; if(diff > tod.hz){ /* convert to epoch */ mul64fract(&x, diff, tod.multiplier); if(x > 30000000000ULL) iprint("todfix %llud\n", x); x += tod.off; /* protect against overflows */ tod.last = ticks; tod.off = x; } iunlock(&tod); }
/* * this is all a bit magic. the soc.exceptvec register is effectively * undocumented. we had to look at linux and experiment, alas. this is the * sort of thing that should be standardised as part of the cortex mpcore spec. * even intel document their equivalent procedure. */ int startcpu(uint cpu) { int i, r; ulong oldvec, rstaddr; ulong *evp = (ulong *)soc.exceptvec; /* magic */ r = 0; if (getncpus() < 2 || cpu == m->machno || cpu >= MAXMACH || cpu >= navailcpus) return -1; oldvec = *evp; l1cache->wb(); /* start next cpu w same view of ram */ *evp = rstaddr = PADDR(_vrst); /* will start cpu executing at _vrst */ coherence(); l1cache->wb(); unfreeze(cpu); for (i = 2000; i > 0 && *evp == rstaddr; i--) delay(1); if (i <= 0 || *evp != cpu) { iprint("cpu%d: didn't start!\n", cpu); stopcpu(cpu); /* make sure it's stopped */ r = -1; } *evp = oldvec; return r; }
static void pass1(int pass, volatile Diag *dp) { int i; if(m->machno == 0) iprint(" %d", pass); for (i = 1000*1000; --i > 0; ) { incref(&dp->cnt); incref(&dp->cnt); } synccpus(&dp->sync, navailcpus); /* all cpus are now here */ ilock(dp); if(dp->cnt.ref != 0) panic("cpu%d: diag: failed w count %ld", m->machno, dp->cnt.ref); iunlock(dp); synccpus(&dp->sync, 2 * navailcpus); /* all cpus are now here */ decref(&dp->sync); decref(&dp->sync); }
/* * Set the time of day struct */ void todset(vlong t, vlong delta, int n) { if(!tod.init) todinit(); ilock(&tod); if(t >= 0){ tod.off = t; tod.last = fastticks(nil); tod.lasttime = 0; tod.delta = 0; tod.sstart = tod.send; } else { if(n <= 0) n = 1; n *= HZ; if(delta < 0 && n > -delta) n = -delta; if(delta > 0 && n > delta) n = delta; if (n == 0) { iprint("todset: n == 0, delta == %lld\n", delta); delta = 0; } else delta /= n; tod.sstart = MACHP(0)->ticks; tod.send = tod.sstart + n; tod.delta = delta; } iunlock(&tod); }
static mng_bool fb_mng_traceproc(mng_handle handle, mng_int32 funcnr, mng_int32 seq, mng_pchar funcname) { iprint(MSG_ERROR, "libmng trace: %s (seq %d\n)", funcname, seq); return MNG_TRUE; }
void panic(char *fmt, ...) { int n; Mpl pl; va_list arg; char buf[PRINTSIZE]; consdevs[1].q = nil; /* don't try to write to /dev/kprint */ if(panicking) for(;;); panicking = 1; pl = splhi(); seprint(buf, buf+sizeof buf, "panic: cpu%d: ", machp()->machno); va_start(arg, fmt); n = vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf; va_end(arg); iprint("%s\n", buf); if(consdebug) (*consdebug)(); splx(pl); //prflush(); buf[n] = '\n'; putstrn(buf, n+1); //dumpstack(); delay(1000); /* give time to consoles */ die("wait forever"); exit(1); }
/* must call with c qlocked */ static void identify(Ctlr *c, SDunit *u) { int n; uvlong s, osectors; uchar buf[sizeof(Dir) + 100]; Dir dir; if(waserror()){ iprint("sdloop: identify: %s\n", up->errstr); nexterror(); } osectors = c->sectors; n = devtab[c->c->type]->stat(c->c, buf, sizeof buf); if(convM2D(buf, n, &dir, nil) == 0) error("internal error: stat error in seek"); s = dir.length / c->sectsize; poperror(); memset(u->inquiry, 0, sizeof u->inquiry); u->inquiry[2] = 2; u->inquiry[3] = 2; u->inquiry[4] = sizeof u->inquiry - 4; memmove(u->inquiry+8, c->path, 40); if(osectors == 0 || osectors != s){ c->sectors = s; c->drivechange = 1; c->vers++; } }