Пример #1
0
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);
}
Пример #2
0
/*
 * 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);
}
Пример #3
0
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);
}
Пример #4
0
Файл: clock.c Проект: 8l/inferno
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));
}
Пример #5
0
/* 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;
	}
}
Пример #6
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;
}
Пример #7
0
/*
 * 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);
			}
		}
	}
}
Пример #8
0
/*
 * 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;
}
Пример #9
0
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;
}
Пример #10
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;
}
Пример #11
0
static void
dumpbytes(uchar *bp, long max)
{
	iprint("%#p: ", bp);
	for (; max > 0; max--)
		iprint("%02.2ux ", *bp++);
	iprint("...\n");
}
Пример #12
0
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);
}
Пример #13
0
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");
}
Пример #14
0
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);
}
Пример #15
0
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 = &ether->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;
}
Пример #16
0
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;
}
Пример #17
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;
}
Пример #18
0
/*
 * 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();
}
Пример #19
0
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();
}
Пример #20
0
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);
	}
}
Пример #21
0
/*
 *  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;
}
Пример #22
0
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);
}
Пример #23
0
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);
}
Пример #24
0
/*
 *  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);
}
Пример #25
0
/*
 * 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;
}
Пример #26
0
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);
}
Пример #27
0
/*
 *  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);
}
Пример #28
0
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;

}
Пример #29
0
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);
}
Пример #30
0
/* 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++;
	}
}