plan 9 kernel history: overview | file list | diff list

1991/0209/power/devhotrod.c (diff list | history)

1990/11211/sys/src/9/power/devhotrod.c:9,521991/0209/sys/src/9/power/devhotrod.c:9,54 (short | long | prev | next)
1990/1013    
#include	"io.h" 
 
typedef struct Hotrod	Hotrod; 
1991/0209    
typedef struct HotQ	HotQ; 
1990/1013    
typedef struct Device	Device; 
1990/1106    
typedef struct Printbuf	Printbuf; 
1990/1013    
 
enum { 
	Vmevec=		0xd2,		/* vme vector for interrupts */ 
	Intlevel=	5,		/* level to interrupt on */ 
1990/1018    
	Nhotrod=	2, 
1991/0209    
	Qdir=		0,		/* Qid's */ 
	Qhotrod=	1, 
	NhotQ=		10,		/* size of communication queues */ 
	Nhotrod=	1, 
1990/1013    
}; 
 
/* 
1990/1106    
 *  circular 2 pointer queue for hotrod prnt's 
 */ 
struct Printbuf { 
	char	*rptr; 
	char	*wptr; 
	char	*lim; 
	char	buf[4*1024]; 
}; 
                 
/* 
1990/1013    
 *  the hotrod fiber interface responds to 1MB 
1991/0209    
 *  The hotrod fiber interface responds to 1MB 
1990/1013    
 *  of either user or supervisor accesses at: 
 *  	0x30000000 to 0x300FFFFF  in	A32 space 
 *  and	  0xB00000 to   0xBFFFFF  in	A24 space 
1991/0209    
 *  and	  0xB00000 to   0xBFFFFF  in	A24 space. 
 *  The second 0x40000 of this space is on-board SRAM. 
1990/1013    
 */ 
struct Device { 
1990/1018    
	ulong	mem[1024*1024/sizeof(ulong)]; 
1991/0209    
	ulong	mem[0x100000/sizeof(ulong)]; 
1990/1013    
}; 
1990/1018    
#define HOTROD		VMEA24SUP(Device, 0xB00000) 
1990/1013    
 
struct Hotrod { 
	QLock; 
1991/0209    
struct HotQ{ 
	ulong	i;			/* index into queue */ 
	Hotmsg	*msg[NhotQ];		/* pointer to command buffer */ 
	ulong	pad[3];			/* unused; for hotrod prints */ 
}; 
1990/1013    
 
1991/0209    
 
struct Hotrod{ 
	QLock; 
	Lock		busy; 
1990/1106    
	Device		*addr;		/* address of the device */ 
	int		vec;		/* vme interrupt vector */ 
	char		name[NAMELEN];	/* hot rod name */ 
	Printbuf	pbuf;		/* circular queue for hotrod print's */ 
	int		kprocstarted; 
1991/0209    
	HotQ		*wq;		/* write this queue to send cmds */ 
	int		wi;		/* where to write next cmd */ 
	HotQ		rq;		/* read this queue to receive replies */ 
	int		ri;		/* where to read next response */ 
1990/1106    
	Rendez		r; 
1990/1013    
}; 
 
1990/11211/sys/src/9/power/devhotrod.c:53,671991/0209/sys/src/9/power/devhotrod.c:55,80
1990/1013    
Hotrod hotrod[Nhotrod]; 
 
1990/1106    
void	hotrodintr(int); 
void	hotrodkproc(void *a); 
1990/1013    
 
int 
hotrodgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) 
1991/0209    
/* 
 * Commands 
 */ 
enum{ 
	RESET=	0,	/* params: Q address, length of queue */ 
	REBOOT=	1,	/* params: none */ 
}; 
 
void 
hotsend(Hotrod *h, Hotmsg *m) 
1990/1013    
{ 
	if(i || c->dev>=Nhotrod) 
		return -1; 
1990/11211    
	devdir(c, (Qid){0,0}, hotrod[c->dev].name, sizeof(Device), 0666, dp); 
1990/1013    
	return 1; 
1991/0209    
print("hotsend send %d %lux %lux\n", m->cmd, m, m->param[0]); 
	h->wq->msg[h->wi] = m; 
	while(h->wq->msg[h->wi]) 
		; 
print("hotsend done\n"); 
	h->wi++; 
	if(h->wi >= NhotQ) 
		h->wi = 0; 
1990/1013    
} 
 
/* 
1990/11211/sys/src/9/power/devhotrod.c:73,831991/0209/sys/src/9/power/devhotrod.c:86,99
1990/1013    
	int i; 
1990/1018    
	Hotrod *hp; 
1990/1013    
 
	for(i=0; i<Nhotrod; i++){ 
		hotrod[i].addr = HOTROD+i; 
		hotrod[i].vec = Vmevec+i; 
		sprint(hotrod[i].name, "hotrod%d", i); 
		setvmevec(hotrod[i].vec, hotrodintr); 
1991/0209    
	for(hp=hotrod,i=0; i<Nhotrod; i++,hp++){ 
		hp->addr = HOTROD+i; 
		/* 
		 * Write queue is at end of hotrod memory 
		 */ 
		hp->wq = (HotQ*)((ulong)hp->addr+2*0x40000-sizeof(HotQ)); 
		hp->vec = Vmevec+i; 
		setvmevec(hp->vec, hotrodintr); 
1990/1013    
	}	 
	wbflush(); 
	delay(20); 
1990/11211/sys/src/9/power/devhotrod.c:102,1111991/0209/sys/src/9/power/devhotrod.c:118,123
1990/1013    
	if(i >= Nhotrod) 
1990/11211    
		error(Ebadarg); 
1990/1013    
 
1990/1106    
	hp = &hotrod[i]; 
	if(hp->kprocstarted == 0) 
		kproc(hp->name, hotrodkproc, hp); 
                 
1990/1013    
	c = devattach('H', spec); 
	c->dev = i; 
1990/11211    
	c->qid.path = CHDIR; 
1990/11211/sys/src/9/power/devhotrod.c:122,1341991/0209/sys/src/9/power/devhotrod.c:134,153
1990/1013    
int	  
hotrodwalk(Chan *c, char *name) 
{ 
	return devwalk(c, name, 0, 0, hotrodgen); 
1991/0209    
	if(c->qid.path != CHDIR) 
		return 0; 
	if(strncmp(name, "hotrod", 6) == 0){ 
		c->qid.path = Qhotrod; 
		return 1; 
	} 
	return 0; 
1990/1013    
} 
 
void	  
hotrodstat(Chan *c, char *dp) 
{ 
	devstat(c, dp, 0, 0, hotrodgen); 
1991/0209    
	print("hotrodstat\n"); 
	error(Egreg); 
1990/1013    
} 
 
Chan* 
1990/11211/sys/src/9/power/devhotrod.c:137,1551991/0209/sys/src/9/power/devhotrod.c:156,183
1990/1106    
	Device *dp; 
	Hotrod *hp; 
 
1990/1110    
#ifdef asdf 
1990/1106    
	/* 
	 *  Remind hotrod where the print buffer is.  The address we store 
	 *  is the address of the printbuf in VME A32 space. 
	 */ 
	hp = &hotrod[c->dev]; 
	dp = hp->addr; 
	dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28); 
1990/1110    
#endif 
1990/1106    
                 
1990/11211    
	if(c->qid.path == CHDIR){ 
1990/1013    
		if(omode != OREAD) 
1990/11211    
			error(Eperm); 
1991/0209    
	}else if(c->qid.path == Qhotrod){ 
		hp = &hotrod[c->dev]; 
		if(!canlock(&hp->busy)) 
			error(Einuse); 
		/* 
		 * Clear communications region 
		 */ 
		memset(hp->wq->msg, 0, sizeof(hp->wq->msg)); 
		hp->wq->i = 0; 
 
		/* 
		 * Issue reset 
		 */ 
		hp->wi = 0; 
		hp->ri = 0; 
		u->khot.cmd = RESET; 
		u->khot.param[0] = (ulong)&hp->rq; 
		u->khot.param[1] = NhotQ; 
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
1990/11211/sys/src/9/power/devhotrod.c:166,1711991/0209/sys/src/9/power/devhotrod.c:194,207
1990/1013    
void	  
hotrodclose(Chan *c) 
{ 
1991/0209    
	Hotrod *hp; 
 
	hp = &hotrod[c->dev]; 
	if(c->qid.path != CHDIR){ 
		u->khot.cmd = REBOOT; 
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
		unlock(&hp->busy); 
	} 
1990/1013    
} 
 
/* 
1990/11211/sys/src/9/power/devhotrod.c:180,1871991/0209/sys/src/9/power/devhotrod.c:216,223
1990/1018    
	ulong *to; 
	ulong *end; 
1990/1013    
 
1990/11211    
	if(c->qid.path & CHDIR) 
1990/1018    
		return devdirread(c, buf, n, 0, 0, hotrodgen); 
1991/0209    
	if(c->qid.path != Qhotrod) 
		error(Egreg); 
1990/1018    
 
	/* 
	 *  allow full word access only 
1990/11211/sys/src/9/power/devhotrod.c:222,2271991/0209/sys/src/9/power/devhotrod.c:258,265
1990/1018    
	ulong *to; 
	ulong *end; 
1990/1013    
 
1991/0209    
	if(c->qid.path != Qhotrod) 
		error(Egreg); 
1990/1018    
	/* 
	 *  allow full word access only 
	 */ 
1990/11211/sys/src/9/power/devhotrod.c:270,3021991/0209/sys/src/9/power/devhotrod.c:308,312
1990/1013    
	if(hp < hotrod || hp > &hotrod[Nhotrod]){ 
		print("bad hotrod vec\n"); 
		return; 
1990/1106    
	} 
} 
                 
/* 
 *  print hotrod processor messages on the console 
 */ 
void 
hotrodkproc(void *a) 
{ 
	Hotrod	*hp = a; 
	char	*p; 
                 
	hp->kprocstarted = 1; 
	hp->pbuf.rptr = hp->pbuf.wptr = hp->pbuf.buf; 
	hp->pbuf.lim = &hp->pbuf.buf[sizeof(hp->pbuf.buf)]; 
                 
	for(;;){ 
		p = hp->pbuf.wptr; 
		if(p != hp->pbuf.rptr){ 
			if(p > hp->pbuf.rptr){ 
				putstrn(hp->pbuf.rptr, p - hp->pbuf.rptr); 
			} else { 
				putstrn(hp->pbuf.rptr, hp->pbuf.lim - hp->pbuf.rptr); 
				putstrn(hp->pbuf.buf, hp->pbuf.wptr - hp->pbuf.buf); 
			} 
			hp->pbuf.rptr = p; 
		} 
		tsleep(&(hp->r), return0, 0, 1000); 
1990/1013    
	} 
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)