⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcmcia.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>enum{	Linktarget = 0x13,	Funcid = 0x21,	End =	0xff,};int fd;int pos;void	tdevice(int, int);void	tlonglnkmfc(int, int);void	tfuncid(int, int);void	tcfig(int, int);void	tentry(int, int);void	tvers1(int, int);void (*parse[256])(int, int) ={[1]		tdevice,[6]		tlonglnkmfc,[0x15]		tvers1,[0x17]		tdevice,[0x1A]		tcfig,[0x1B]		tentry,[Funcid]	tfuncid,};int hex;voidfatal(char *fmt, ...){	va_list arg;	char buf[512];	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	fprint(2, "pcmcia: %s\n", buf);	exits(buf);}intreadc(void *x){	int rv;	seek(fd, 2*pos, 0);	pos++;	rv = read(fd, x, 1);	if(hex)		print("%2.2ux ", *(uchar*)x);	return rv;}inttuple(int next, int expect){	uchar link;	uchar type;	pos = next;	if(readc(&type) != 1)		return -1;	if(type == 0xff)		return -1;print("type %.2uX\n", type & 0xff);	if(expect && expect != type){		print("expected %.2uX found %.2uX\n", 			expect, type);		return -1;	}	if(readc(&link) != 1)		return -1;	if(parse[type])		(*parse[type])(type, link);	if(link == 0xff)		next = -1;	else		next = next+2+link;	return next;}voidmain(int argc, char *argv[]){	char *file;	int next;	ARGBEGIN{	case 'x':		hex = 1;	}ARGEND;	if(argc == 0)		file = "#y/pcm0attr";	else		file = argv[0];	fd = open(file, OREAD);	if(fd < 0)		fatal("opening %s: %r", file);	for(next = 0; next >= 0;)		next = tuple(next, 0);}ulong speedtab[16] ={[1]	250,[2]	200,[3]	150,[4]	100,};ulong mantissa[16] ={[1]	10,[2]	12,[3]	13,[4]	15,[5]	20,[6]	25,[7]	30,[8]	35,[9]	40,[0xa]	45,[0xb]	50,[0xc]	55,[0xd]	60,[0xe]	70,[0xf]	80,};ulong exponent[8] ={[0]	1,[1]	10,[2]	100,[3]	1000,[4]	10000,[5]	100000,[6]	1000000,[7]	10000000,};char *typetab[256] ={[1]	"Masked ROM",[2]	"PROM",[3]	"EPROM",[4]	"EEPROM",[5]	"FLASH",[6]	"SRAM",[7]	"DRAM",[0xD]	"IO+MEM",};ulonggetlong(int size){	uchar c;	int i;	ulong x;	x = 0;	for(i = 0; i < size; i++){		if(readc(&c) != 1)			break;		x |= c<<(i*8);	}	return x;}voidtdevice(int ttype, int len){	uchar id;	uchar type;	uchar speed, aespeed;	uchar size;	ulong bytes, ns;	char *tname, *ttname;	while(len > 0){		if(readc(&id) != 1)			return;		len--;		if(id == End)			return;		/* PRISM cards have a device tuple with id = size = 0. */		if(id == 0x00){			if(readc(&size) != 1)				return;			len--;			continue;		}		speed = id & 0x7;		if(speed == 0x7){			if(readc(&speed) != 1)				return;			len--;			if(speed & 0x80){				if(readc(&aespeed) != 1)					return;				ns = 0;			} else				ns = (mantissa[(speed>>3)&0xf]*exponent[speed&7])/10;		} else			ns = speedtab[speed];		type = id>>4;		if(type == 0xE){			if(readc(&type) != 1)				return;			len--;		}		tname = typetab[type];		if(tname == 0)			tname = "unknown";		if(readc(&size) != 1)			return;		len--;		bytes = ((size>>3)+1) * 512 * (1<<(2*(size&0x7)));		if(ttype == 1)			ttname = "device";		else			ttname = "attr device";		print("%s %ld bytes of %ldns %s\n", ttname, bytes, ns, tname);	}}voidtlonglnkmfc(int, int){	int i, opos;	uchar nfn, space, expect;	int addr;	readc(&nfn);	for(i = 0; i < nfn; i++){		readc(&space);		addr = getlong(4);		opos = pos;		expect = Linktarget;		while(addr > 0){			addr = tuple(addr, expect);			expect = 0;		}		pos = opos;	}}static char *funcids[] = {	"MULTI",	"MEMORY",	"SERIAL",	"PARALLEL",	"FIXED",	"VIDEO",	"NETWORK",	"AIMS",	"SCSI",};voidtfuncid(int, int){	uchar func;	readc(&func);	print("Function %s\n", 		(func >= nelem(funcids))? "unknown function": funcids[func]);}voidtvers1(int ttype, int len){	uchar c, major, minor;	int  i;	char string[512];	USED(ttype);	if(readc(&major) != 1)		return;	len--;	if(readc(&minor) != 1)		return;	len--;	print("version %d.%d\n", major, minor);	while(len > 0){		for(i = 0; len > 0 && i < sizeof(string); i++){			if(readc(&string[i]) != 1)				return;			len--;			c = string[i];			if(c == 0)				break;			if(c == 0xff){				if(i != 0){					string[i] = 0;					print("\t%s<missing null>\n", string);				}				return;			}		}		string[i] = 0;		print("\t%s\n", string);	}}voidtcfig(int ttype, int len){	uchar size, rasize, rmsize;	uchar last;	ulong caddr;	ulong cregs;	int i;	USED(ttype, len);	if(readc(&size) != 1)		return;	rasize = (size&0x3) + 1;	rmsize = ((size>>2)&0xf) + 1;	if(readc(&last) != 1)		return;	caddr = getlong(rasize);	cregs = getlong(rmsize);	print("configuration registers at");	for(i = 0; i < 16; i++)		if((1<<i) & cregs)			print(" (%d)0x%lux", i, caddr + i*2);	print("\n");}char *intrname[16] ={[0]	"memory",[1]	"I/O",[4]	"Custom 0",[5]	"Custom 1",[6]	"Custom 2",[7]	"Custom 3",};ulong vexp[8] ={	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};ulong vmant[16] ={	10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90,};voidvolt(char *name){	uchar c;	ulong microv;	ulong exp;	if(readc(&c) != 1)		return;	exp = vexp[c&0x7];	microv = vmant[(c>>3)&0xf]*exp;	while(c & 0x80){		if(readc(&c) != 1)			return;		switch(c){		case 0x7d:			break;		/* high impedence when sleeping */		case 0x7e:		case 0x7f:			microv = 0;	/* no connection */			break;		default:			exp /= 10;			microv += exp*(c&0x7f);		}	}	print(" V%s %lduV", name, microv);}voidamps(char *name){	uchar c;	ulong amps;	if(readc(&c) != 1)		return;	amps = vexp[c&0x7]*vmant[(c>>3)&0xf];	while(c & 0x80){		if(readc(&c) != 1)			return;		if(c == 0x7d || c == 0x7e || c == 0x7f)			amps = 0;	}	if(amps >= 1000000)		print(" I%s %ldmA", name, amps/100000);	else if(amps >= 1000)		print(" I%s %lduA", name, amps/100);	else		print(" I%s %ldnA", name, amps*10);}voidpower(char *name){	uchar feature;	print("\t%s: ", name);	if(readc(&feature) != 1)		return;	if(feature & 1)		volt("nominal");	if(feature & 2)		volt("min");	if(feature & 4)		volt("max");	if(feature & 8)		amps("static");	if(feature & 0x10)		amps("avg");	if(feature & 0x20)		amps("peak");	if(feature & 0x40)		amps("powerdown");	print("\n");}voidttiming(char *name, int scale){	uchar unscaled;	ulong scaled;	if(readc(&unscaled) != 1)		return;	scaled = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10;	scaled = scaled * vexp[scale];	print("\t%s %ldns\n", name, scaled);}voidtiming(void){	uchar c, i;	if(readc(&c) != 1)		return;	i = c&0x3;	if(i != 3)		ttiming("max wait", i);	i = (c>>2)&0x7;	if(i != 7)		ttiming("max ready/busy wait", i);	i = (c>>5)&0x7;	if(i != 7)		ttiming("reserved wait", i);}voidrange(int asize, int lsize){	ulong address, len;	address = getlong(asize);	len = getlong(lsize);	print("\t\t%lux - %lux\n", address, address+len);}char *ioaccess[4] ={	" no access",	" 8bit access only",	" 8bit or 16bit access",	" selectable 8bit or 8&16bit access",};intiospace(uchar c){	int i;	print("\tIO space %d address lines%s\n", c&0x1f, ioaccess[(c>>5)&3]);	if((c & 0x80) == 0)		return -1;	if(readc(&c) != 1)		return -1;	for(i = (c&0xf)+1; i; i--)		range((c>>4)&0x3, (c>>6)&0x3);	return 0;}voidiospaces(void){	uchar c;	if(readc(&c) != 1)		return;	iospace(c);}voidirq(void){	uchar c;	uchar irq1, irq2;	ushort i, irqs;	if(readc(&c) != 1)		return;	if(c & 0x10){		if(readc(&irq1) != 1)			return;		if(readc(&irq2) != 1)			return;		irqs = irq1|(irq2<<8);	} else		irqs = 1<<(c&0xf);	print("\tinterrupts%s%s%s", (c&0x20)?":level":"", (c&0x40)?":pulse":"",		(c&0x80)?":shared":"");	for(i = 0; i < 16; i++)		if(irqs & (1<<i))			print(", %d", i);	print("\n");}voidmemspace(int asize, int lsize, int host){	ulong haddress, address, len;	len = getlong(lsize)*256;	address = getlong(asize)*256;	if(host){		haddress = getlong(asize)*256;		print("\tmemory address range 0x%lux - 0x%lux hostaddr 0x%lux\n",			address, address+len, haddress);	} else		print("\tmemory address range 0x%lux - 0x%lux\n", address, address+len);}voidmisc(void){}voidtentry(int ttype, int len){	uchar c, i, feature;	char *tname;	char buf[16];	USED(ttype, len);	if(readc(&c) != 1)		return;	print("configuration %d%s\n", c&0x3f, (c&0x40)?" (default)":"");	if(c & 0x80){		if(readc(&i) != 1)			return;		tname = intrname[i & 0xf];		if(tname == 0){			tname = buf;			sprint(buf, "type %d", i & 0xf);		}		print("\t%s device, %s%s%s%s\n", tname,			(i&0x10)?" Battery status active":"",			(i&0x20)?" Write Protect active":"",			(i&0x40)?" Ready/Busy active":"",			(i&0x80)?" Memory Wait required":"");	}	if(readc(&feature) != 1)		return;	switch(feature&0x3){	case 1:		power("Vcc");		break;	case 2:		power("Vcc");		power("Vpp");		break;	case 3:		power("Vcc");		power("Vpp1");		power("Vpp2");		break;	}	if(feature&0x4)		timing();	if(feature&0x8)		iospaces();	if(feature&0x10)		irq();	switch((feature>>5)&0x3){	case 1:		memspace(0, 2, 0);		break;	case 2:		memspace(2, 2, 0);		break;	case 3:		if(readc(&c) != 1)			return;		for(i = 0; i <= (c&0x7); i++)			memspace((c>>5)&0x3, (c>>3)&0x3, c&0x80);		break;	}	if(feature&0x80)		misc();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -