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

📄 devastar.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 3 页
字号:
		if(ioalloc(a->port, 6, 0, name) < 0){			print("#G%d: port 0x%lux in use\n", a->id, a->port);			return -1;		}		found = astarprobe(a->port);	}	if(!found){		print("#G%d: not found\n", a->id);		iofree(a->port);		return -1;	}	/* check interrupt level */	if(isairqcode[a->irq] == -1){		print("#G%d: bad irq %lud\n", a->id, a->irq);		iofree(a->port);		return -1;	}	/* set ISA memory address */	outb(a->port+ISAmaddr, (a->mem>>12) & 0xfc);	a->gcb = KADDR(a->mem);	a->addr = KADDR(a->mem);	/* disable ISA memory response */	outb(a->port+ISActl2, 0);	a->memsize = 0;	a->page = -1;	/* reset processor */	outb(a->port+ISActl1, 0);	return 0;}static Chan*astarattach(char *spec){	ulong ctlrno;	char *p;	ctlrno = 0;	if(spec && *spec){		ctlrno = strtoul(spec, &p, 0);		if((ctlrno == 0 && p == spec) || *p || (ctlrno >= Maxcard))			error(Ebadarg);	}	if(astar[ctlrno] == nil)		error(Enodev);	return devattach('G', spec);}static intastarwalk(Chan *c, char *name){	return devwalk(c, name, 0, 0, astargen);}static voidastarstat(Chan *c, char *dp){	devstat(c, dp, 0, 0, astargen);}static Chan*astaropen(Chan *c, int omode){	Astar *a;	Astarchan *ac;	c = devopen(c, omode, 0, 0, astargen);	a = astar[BOARD(c->qid.path)];	switch(TYPE(c->qid.path)){	case Qmem:	case Qbctl:		if(!iseve())			error(Eperm);		break;	case Qdata:	case Qctl:		ac = a->c + CHAN(c->qid.path);		qlock(ac);		if(waserror()){			qunlock(ac);			ac->opens--;			nexterror();		}		if(ac->opens++ == 0){			enable(ac);			qreopen(ac->iq);			qreopen(ac->oq);		}		qunlock(ac);		poperror();		break;	}	return c;}static voidastarclose(Chan *c){	Astar *a;	Astarchan *ac;	if((c->flag & COPEN) == 0)		return;	a = astar[BOARD(c->qid.path)];	switch(TYPE(c->qid.path)){	case Qdata:	case Qctl:		ac = a->c + CHAN(c->qid.path);		qlock(ac);		if(waserror()){			qunlock(ac);			nexterror();		}		if(--(ac->opens) == 0){			disable(ac);			qclose(ac->iq);			qclose(ac->oq);		}		qunlock(ac);		poperror();		break;	}}/* *  read PCI mapped memory */static longpcimemread(Astar *a, uchar *to, long n, ulong offset){	uchar *from;	int rem;	if(offset+n > a->memsize){		if(offset >= a->memsize)			return 0;		n = a->memsize - offset;	}	from = a->addr+offset;	for(rem = n; rem > 0; rem--)		*to++ = *from++;	return n;}/* *  read ISA mapped memory */static longisamemread(Astar *a, uchar *to, long n, ulong offset){	uchar *from, *e, *tp;	int i, rem;	uchar tmp[256];	if(offset+n > a->memsize){		if(offset >= a->memsize)			return 0;		n = a->memsize - offset;	}	for(rem = n; rem > 0; rem -= i){		/* map in right piece of memory */		i = offset&Pagemask;		from = a->addr + i;		i = Pagesize - i;		if(i > rem)			i = rem;		if(i > sizeof(tmp))			i = sizeof(tmp);		/*		 *  byte at a time so endian doesn't matter,		 *  go via tmp to avoid pagefaults while ilock'd		 */		tp = tmp;		LOCKPAGE(a, offset);		for(e = tp + i; tp < e;)			*tp++ = *from++;		UNLOCKPAGE(a);		memmove(to, tmp, i);		to += i;		offset += i;	}	return n;}/* *  read ISA status */static longbctlread(Astar *a, void *buf, long n, ulong offset){	char s[128];	if(a->pci)		sprint(s, "range %luX remap %luX region %luX mailbox %luX doorbell0 %luX doorbell1 %luX control %luX command %luX",			inl(a->port+PCIrange),			inl(a->port+PCIremap),			inl(a->port+PCIregion),			inl(a->port+PCImailbox),			inl(a->port+PCIdoorbell0),			inl(a->port+PCIdoorbell1),			inl(a->port+PCIcontrol),			inl(a->port+PCIcommand));	else		sprint(s, "id %4.4ux ctl1 %2.2ux ctl2 %2.2ux maddr %2.2ux stat %4.4ux",			(inb(a->port+ISAid)<<8)|inb(a->port+ISAid),			inb(a->port+ISActl1), inb(a->port+ISActl2), 			inb(a->port+ISAmaddr),			(inb(a->port+ISAstat2)<<8)|inb(a->port+ISAstat1));	return readstr(offset, buf, n, s);}static longstatread(Astarchan *ac, void *buf, long n, ulong offset){	char s[256];	int mstat, bstat, fstat;	LOCKPAGE(ac->a, 0);	mstat = LEUS(ac->ccb->mstat);	bstat = LEUS(ac->ccb->bstat);	fstat = LEUS(ac->ccb->format);	UNLOCKPAGE(ac->a);	snprint(s, sizeof s,		"b%d c%d d%d e%d l%d m%d p%c r%d s%d\n"		"%ld %d %d%s%s%s%s\n",		ac->baud,		ac->hup_dcd,		ac->dtr,		ac->hup_dsr,		(fstat & Clenmask),		0, 	/* change in modem status? */		(fstat & Cparmask) ? ((fstat & Cevenpar) == Cevenpar ? 'e' : 'o') : 'n',		(bstat & Crbrts) ? 1 : 0,		(fstat & C2stop) ? 2 : 1,		ac - ac->a->c,		ac->framing,		ac->overrun,		(mstat & Cctsstat)    ? " cts"  : "",		(mstat & Cdsrstat)    ? " dsr"  : "",		(mstat & Cdcdstat)    ? " dcd"  : "",		(mstat & Cristat)   ? " ring" : ""	);	return readstr(offset, buf, n, s);}static longastarread(Chan *c, void *buf, long n, vlong off){	Astar *a;	Astarchan *ac;	ulong offset = off;	if(c->qid.path & CHDIR)		return devdirread(c, buf, n, 0, 0, astargen);	switch(TYPE(c->qid.path)){	case Qstat:		a = astar[BOARD(c->qid.path)];		return statread(a->c + CHAN(c->qid.path), buf, n, offset);	case Qmem:		a = astar[BOARD(c->qid.path)];		if(a->pci)			return pcimemread(a, buf, n, offset);		return isamemread(a, buf, n, offset);	case Qbctl:		return bctlread(astar[BOARD(c->qid.path)], buf, n, offset);	case Qdata:		a = astar[BOARD(c->qid.path)];		ac = a->c + CHAN(c->qid.path);		return qread(ac->iq, buf, n);	}	return 0;}/* *  write PCI mapped memory */static longpcimemwrite(Astar *a, uchar *from, long n, ulong offset){	uchar *to;	int rem;	ulong limit;	/*	 * Disallow writes above 0xD000 where the i960	 * data structures live if writing in the lower bank.	 */	if(a->addr == (uchar*)a->mem)		limit = 0xD000;	else		limit = a->memsize;	if(offset+n > limit){		if(offset >= limit)			return 0;		n = limit - offset;	}	to = a->addr+offset;	for(rem = n; rem > 0; rem--)		*to++ = *from++;	return n;}/* *  write ISA mapped memory */static longisamemwrite(Astar *a, uchar *from, long n, ulong offset){	uchar *to, *e, *tp;	int i, rem;	uchar tmp[256];	if(offset+n > a->memsize){		if(offset >= a->memsize)			return 0;		n = a->memsize - offset;	}	for(rem = n; rem > 0; rem -= i){		/* map in right piece of memory */		i = offset&Pagemask;		to = a->addr + i;		i = Pagesize - i;		if(i > rem)			i = rem;		if(i > sizeof(tmp))			i = sizeof(tmp);				/*		 *  byte at a time so endian doesn't matter,		 *  go via tmp to avoid pagefaults while ilock'd		 */		memmove(tmp, from, i);		tp = tmp;		LOCKPAGE(a, offset);		for(e = tp + i; tp < e;)			*to++ = *tp++;		UNLOCKPAGE(a);		from += i;		offset += i;	}	return n;}/* *  put board into download mode */static voiddownloadmode(Astar *a){	int c, i;	/* put board in download mode */	if(a->pci){		/*		 * Don't let the download write over the		 * i960 data structures.		 */		a->memsize = 0xD000;		a->addr = (uchar*)a->mem;	}	else{		a->memsize = Pramsize;		a->needpage = 1;		c = inb(a->port+ISActl1);		outb(a->port+ISActl1, c & ~ISAnotdl);		/* give it up to 5 seconds to reset */		for(i = 0; i < 21; i++){			if(!(inb(a->port+ISActl1) & ISAnotdl))				break;			tsleep(&a->r, return0, 0, 500);		}		if(inb(a->port+ISActl1) & ISAnotdl){			print("#G%d: did not reset\n", a->id);			error(Eio);		}		/* enable ISA access to first 16k */		a->page = -1;		setpage(a, 0);	}}/* *  start control program */static voidstartcp(Astar *a){	int c, n, i, sz;	uchar *x;	CCB *ccb;	Astarchan *ac;	char name[10];	if(a->running)		error(Eio);	/* take board out of download mode and enable IRQ */	if(a->pci){		outl(a->port+PCImailbox, 1);		/* wait for control program to signal life */		delay(100);		for(i = 0; i < 10; i++){			if(inl(a->port+PCImailbox) & 0x80000000)				break;			tsleep(&a->r, return0, 0, 100);		}		if(!(inl(a->port+PCImailbox) & 0x80000000)){			print("#G%d: program not ready\n", a->id);			//error(Eio);		}		a->addr = (uchar*)(a->mem+0x10000);	}	else{		c = inb(a->port+ISActl1);		outb(a->port+ISActl1, c|ISAien|ISAnotdl);		/* wait for control program to signal life */		for(i = 0; i < 21; i++){			if(inb(a->port+ISActl1) & ISApr)				break;			tsleep(&a->r, return0, 0, 500);		}		if((inb(a->port+ISActl1) & ISApr) == 0){			print("#G%d: program not ready\n", a->id);			error(Eio);		}	}	a->memsize = a->ramsize;	if(a->pci || a->memsize <= Pagesize)		a->needpage = 0;	else{		a->page = -1;		setpage(a, 0);		a->needpage = 1;	}	if(waserror()){		UNLOCKPAGE(a);		poperror();	}	LOCKPAGE(a, 0);	i = LEUS(a->gcb->type);	switch(i){	default:		print("#G%d: wrong board type %uX\n", a->id, i);		error(Eio);	case 0x0C:	case 0x12:					/* AvanstarXp */		break;	}	/* check assumptions */	n = LEUS(a->gcb->ccbn);	if(n != 8 && n != 16){		print("#G%d: has %d channels?\n", a->id, i);		error(Eio);	}	x = a->addr + LEUS(a->gcb->ccboff);	sz = LEUS(a->gcb->ccbsz);	if(x+n*sz > a->addr+Pagesize){		print("#G%d: ccb's not in 1st page\n", a->id);		error(Eio);	}	for(i = 0; i < n; i++){		ccb = (CCB*)(x + i*sz);		if(APAGE(LEUS(ccb->inbase)) != APAGE(LEUS(ccb->inlim)) ||		   APAGE(LEUS(ccb->outbase)) != APAGE(LEUS(ccb->outlim))){			print("#G%d: chan buffer spans pages\n", a->id);			error(Eio);		}	}	UNLOCKPAGE(a);	poperror();	/* setup the channels */	a->running = 1;	a->nchan = i;	a->c = smalloc(a->nchan * sizeof(Astarchan));	for(i = 0; i < a->nchan; i++){		ac = &a->c[i];		ac->a = a;		ac->ccb = (CCB*)x;		ac->baud = 9600;	/* a100i default */		ac->perm = 0660;		ac->iq = qopen(4*1024, 0, astarkickin, ac);		ac->oq = qopen(4*1024, 0, astarkick, ac);		x += sz;	}	snprint(name, sizeof name, "astar%d", a->id);	/* set up interrupt level, enable interrupts */	if(a->pci){		/*		 * Which bits in the interrupt control register should be set?		 */		outl(a->port+PCIcontrol, 0x00031F00);		intrenable(a->irq, astarintr, a, a->pci->tbdf, name);	}	else{		c = inb(a->port+ISActl1);		c &= ~ISAirq;		c |= ISAien|isairqcode[a->irq];		outb(a->port+ISActl1, c);		intrenable(a->irq, astarintr, a, BUSUNKNOWN, name);	}	/* enable control program interrupt generation */	LOCKPAGE(a, 0);	a->gcb->cmd2 = LEUS(Gintack);	UNLOCKPAGE(a);}static voidbctlwrite(Astar *a, char *cmsg){	if(waserror()){		qunlock(a);		nexterror();	}	qlock(a);	if(a->running)		error(Eio);	if(strncmp(cmsg, "download", 8) == 0){		/* put board in download mode */		downloadmode(a);

⌨️ 快捷键说明

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