~kris/9p

9hist

f41f05e8cdc76ca8dce29bc93988920391c3f17c — David du Colombier 25 years ago c4bda6a
Plan 9 from Bell Labs 2000-12-09
3 files changed, 67 insertions(+), 36 deletions(-)

M bitsy/devflash.c
M bitsy/power.c
M port/devdraw.c
M bitsy/devflash.c => bitsy/devflash.c +66 -34
@@ 71,6 71,11 @@ struct
	ulong		*wb;		/* staging area for write buffer */
} flash;

enum
{
	Maxwchunk=	1024,	/* maximum chunk written by one call to falg->write */
};

/*
 *  common flash interface
 */


@@ 128,7 133,7 @@ cfiquery(void)
		addr += flash.r[q].size*flash.r[q].n;
		flash.r[q].end = addr;
	}
	flash.wb = malloc(flash.wbsize);
	flash.wb = malloc(flash.wbsize>1024 ? flash.wbsize : 1024);
}

/*


@@ 506,7 511,10 @@ flashdatawrite(Chan *c, uchar *p, long n, long off)
		m = blockend(off) - off;
		if(m > end - p)
			m = end - p;
		(*flash.alg->write)(p, m, off);
		if(m > Maxwchunk)
			m = Maxwchunk;
		memmove(flash.wb, p, m);
		(*flash.alg->write)(flash.wb, m, off);
		off += m;
	}



@@ 561,6 569,21 @@ Dev flashdevtab = {
	devwstat,
};

enum
{
	/* status register */
	ISEs_lockerr=		1<<1,
	ISEs_powererr=		1<<3,
	ISEs_progerr=		1<<4,
	ISEs_eraseerr=		1<<5,
	ISEs_ready=		1<<7,
	ISEs_err= (ISEs_lockerr|ISEs_powererr|ISEs_progerr|ISEs_eraseerr),

	/* extended status register */
	ISExs_bufavail=		1<<7,
};



/* intel/sharp extended command set */
static void


@@ 588,16 611,16 @@ ise_error(int bank, ulong status)
{
	char err[ERRLEN];

	if(status & (1<<3)){
		sprint(err, "flash%d: low prog voltage", bank);
	if(status & (ISEs_lockerr)){
		sprint(err, "flash%d: block locked %lux", bank, status);
		error(err);
	}
	if(status & (1<<1)){
		sprint(err, "flash%d: block locked", bank);
	if(status & (ISEs_powererr)){
		sprint(err, "flash%d: low prog voltage %lux", bank, status);
		error(err);
	}
	if(status & (1<<5)){
		sprint(err, "flash%d: i/o error", bank);
	if(status & (ISEs_progerr|ISEs_eraseerr)){
		sprint(err, "flash%d: i/o error %lux", bank, status);
		error(err);
	}
}


@@ 615,7 638,7 @@ ise_erase(ulong addr)
	start = m->ticks;
	do {
		x = flash.p[addr];
		if((x & mirror(1<<7)) == mirror(1<<7))
		if((x & mirror(ISEs_ready)) == mirror(ISEs_ready))
			break;
	} while(TK2MS(m->ticks-start) < 1500);
	flashprogpower(0);


@@ 627,7 650,7 @@ ise_erase(ulong addr)
	ise_reset();
}
/*
 *  flash writing goes about 16 times faster if we use
 *  the flash spec claimes writing goes faster if we use
 *  the write buffer.  We fill the write buffer and then
 *  issue the write request.  After the write request,
 *  subsequent reads will yield the status register or,


@@ 637,44 660,60 @@ ise_erase(ulong addr)
 *  On timeout, we issue a read status register request so
 *  that the status register can be read no matter how we
 *  exit.
 *
 *  returns the status.
 */
static int
ise_wbwrite(ulong *p, int n, ulong off)
static ulong
ise_wbwrite(ulong *p, int n, ulong off, ulong baddr, ulong *status)
{
	ulong start;
	ulong x, start;
	int i;

	/* copy out of user space to avoid faults later */
	memmove(flash.wb, p, n*4);
	p = flash.wb;
	int s;

	/* put flash into write buffer mode */
	start = m->ticks;
	for(;;) {
		s = splhi();
		/* request write buffer mode */
		flash.p[off] = mirror(0xe8);
		flash.p[baddr] = mirror(0xe8);

		/* look at extended status reg for status */
		if((flash.p[off] & mirror(1<<7)) == mirror(1<<7))
		if((flash.p[baddr] & mirror(1<<7)) == mirror(1<<7))
			break;
		splx(s);

		/* didn't work, keep trying for 2 secs */
		if(TK2MS(m->ticks-start) > 2000){
			/* set up to read status */
			flash.p[off] = mirror(0x70);
			flash.p[baddr] = mirror(0x70);
			*status = flash.p[baddr];
			pprint("write buffered cmd timed out\n");
			return -1;
		}
	}

	/* fill write buffer */
	flash.p[off] = mirror(n-1);
	flash.p[baddr] = mirror(n-1);
	for(i = 0; i < n; i++)
		flash.p[off+i] = *p++;

	/* program from buffer */
	flash.p[off] = mirror(0xd0);
	flash.p[baddr] = mirror(0xd0);
	splx(s);

	/* subsequent reads will return status about the write */
	/* wait till the programming is done */
	start = m->ticks;
	for(;;) {
		x = *status = flash.p[baddr];	/* read status register */
		if((x & mirror(ISEs_ready)) == mirror(ISEs_ready))
			break;
		if(TK2MS(m->ticks-start) > 2000){
			pprint("read status timed out\n");
			return -1;
		}
	}
	if(x & mirror(ISEs_err))
		return -1;

	return n;
}


@@ 683,14 722,15 @@ ise_write(void *a, long n, ulong off)
{
	ulong *p, *end;
	int i, wbsize;
	ulong x, start, ooff;
	ulong x, baddr;

	/* everything in terms of ulongs */
	wbsize = flash.wbsize>>2;
	baddr = blockstart(off);
	off >>= 2;
	n >>= 2;
	p = a;
	ooff = off;
	baddr >>= 2;

	/* first see if write will succeed */
	for(i = 0; i < n; i++)


@@ 715,7 755,7 @@ ise_write(void *a, long n, ulong off)
		if(i > end - p)
			i = end - p;

		if(ise_wbwrite(p, i, off) != i)
		if(ise_wbwrite(p, i, off, baddr, &x) < 0)
			break;

		off += i;


@@ 723,14 763,6 @@ ise_write(void *a, long n, ulong off)
		i = wbsize;
	}

	/* wait till the programming is done */
	start = m->ticks;
	do {
		x = flash.p[ooff];
		if((x & mirror(1<<7)) == mirror(1<<7))
			break;
	} while(TK2MS(m->ticks-start) < 1000);

	ise_clearerror();
	ise_error(0, x);
	ise_error(1, x>>16);

M bitsy/power.c => bitsy/power.c +1 -1
@@ 76,5 76,5 @@ idlehands(void)
void
idlehands(void)
{
//	doze();
	doze();
}

M port/devdraw.c => port/devdraw.c +0 -1
@@ 1364,7 1364,6 @@ drawmesg(Client *client, void *av, int n)
			}
			i = allocmemimage(r, chan);
			if(i == 0){
				iprint("chan %lux\n", chan);
				error(Edrawmem);
			}
			if(repl)