pdp11v/usr/src/cmd/sysdef.c

Compare this file to the similar file:
Show the results in this format:

/*	@(#)sysdef.c	1.3	*/
#include	"stdio.h"
#include	"sys/var.h"
#include	"a.out.h"
#include	"sys/param.h"

#define	PAGESZ	512
#define	D7	0x38000000	/* From Unibus vector table in univec.c */
#define	USRMASK	0x3fffffff
#define	MAPSZ	4
#define	MAXI	200
#define	BUS	0340
#define	CC	0037
#define	BLOCK	010
#define	INTR	0	/* l_nptr[0] for interrupt routines */
#define	ADDR	1	/* l_nptr[1] for device address     */
#define	CNT	2	/* l_nptr[2] for device count       */
#define	STRAT	3	/* l_nptr[3] for strategy if blkdev */

#define	INTSZ		sizeof (int)
#define	SYM_VALUE(ptr)	(ptr->n_value & USRMASK)
#define	N_IFC		((start->n_value - IFC) / IFC_SZ)
#define	TXT		(HDR + aout.a_data)

struct	var	v;
#ifdef vax
struct sgs {
	struct filehdr filehdr;
	struct aouthdr aout;
	struct scnhdr scnhdr[3];
} sgs;
#define	HDR		sizeof (struct sgs)
#else
struct	exec	aout;
#define	HDR		sizeof (struct exec)
#endif
char	*os = "/unix";
char	*mr = "/etc/master";
char	line[256], nm[20], pre[20], intrnm[20],
	devaddr[20], devcnt[20], strat[20];
int	x, address, vsz, unit, bus, deft,
	count, typ, bcnt, maus, mcnt, smem, mesg, sem,
	root, swap, dump, n_swap, power, pipe;
long	swap_low;
int	IFC = 01000;	/* Start of Interface routines */
int	*vec, nexus;
int	bndry();
int	offset;
FILE	*system, *mast, *sysseek;

struct nlist	nl[MAXI], *nlptr, *setup(), *endnm, *start,
	*Messag, *Sema, *Maus, *bdevcnt, *bdevsw, *X25, *mbacnt,
	*rootdev, *swapdev, *dumpdev, *swplo, *nswap, *Shmem,
	*pipedev, *Power, *UNIvec, *umemvad, *Mbacf,
	*vs, *smap, *cmap, *callo, *restart;

struct	link {
	char	l_cfnm[8];	/* config name from master table */
	struct	nlist	*l_nptr;/* ptr to name list structure */
	int	l_vsz;		/* vector size */
	int	l_def;		/* default unit count */
	int	l_dtype;		/* device type - BLOCK */
	int	l_bus;		/* bus request from master table */
	char	l_used;		/* set when device entry is printed */
} ln[MAXI/3], *lnptr, *setln(), *endln, *search(), *majsrch();

struct	vector {
#ifdef	vax
	int	vaxvec;
#endif
#ifdef	pdp11
	int	v_pc;
	int	v_psw;
#endif
} vector, *addr;

struct mbacf {
	int	nexus;
	int	bus_req;
	int	dev_addr;
} mbadev;

struct	bdev {
	int	b_open;
	int	b_close;
	int	b_strategy;
	int	b_tab;
} bent;

#ifdef	pdp11
struct	interface {	/* jsr r5, call; function */
	int	i_jsr;
	int	i_call;
	int	i_func;
} ifc[MAXI/3];

struct	xinterface {	/* jsr r5, call; jmp function */
	int	i_jsr;
	int	i_call;
	int	i_jmp;
	int	i_func;
} xifc[MAXI/3];

int	ovly = 0;	/* set to 1 if overlay system */
int	IFC_SZ = sizeof(ifc[0]);
#endif

struct x25info{
	int	x25_0_0;
	int	x25_0_1;
	int	x25links;
	int	x25bufs;
	int	x25bytes;
} x25info;

main(argc, argv)
	int	argc;
	char	**argv;
{

	register int i;

	switch(argc) {
	case 3:	mr = argv[2];
	case 2: os = argv[1];
	case 1: break;
	default:
		fprintf(stderr, "usage: sysdef  [ /unix [ /etc/master ] ]");
		exit(1);
	}

#ifdef	pdp11
	offset = (-HDR);
#endif

	if((system = fopen(os,"r")) == NULL) {
		fprintf(stderr,"cannot read %s\n",os);
		exit(1);
	}

/* read in a.out header */
#ifdef vax
	if(fread(&sgs, sizeof sgs, 1, system) != 1) {
#else
	if(fread(&aout, sizeof aout, 1, system) != 1) {
#endif
		printf("cannot read a.out header\n");
		exit(1);
	}
#ifdef vax
	if(sgs.aout.magic != 0410) {
#else
	if(BADMAG(aout)) {
#endif
		printf("invalid a.out format\n");
		exit(1);
	}
#ifdef	vax
	offset = PAGESZ - (sgs.aout.tsize % PAGESZ) - HDR;
#endif
#ifdef pdp11
	ovly = (aout.a_magic == A_MAGIC5);
	if (ovly) printf ("* PDP11 overlay system\n");
#endif
	if((sysseek = fopen(os,"r")) == NULL) {
		fprintf(stderr,"cannot read %s\n",os);
		exit(1);
	}
	if((mast = fopen(mr, "r")) == NULL) {
		fprintf(stderr, "cannot read %s\n", mr);
		exit(1);
	}

	nlptr = nl;
	lnptr = ln;
	start = setup("start");
	restart = setup("restart");
	UNIvec = setup("_UNIvec");
	Mbacf = setup("_mbacf");
	umemvad = setup("_umemvad");
	bdevcnt = setup("_bdevcnt");
	mbacnt = setup("_mba_cnt");
	bdevsw = setup("_bdevsw");
	rootdev = setup("_rootdev");
	pipedev = setup("_pipedev");
	swapdev = setup("_swapdev");
	swplo = setup("_swplo");
	nswap = setup("_nswap");
	dumpdev = setup("_dumpdev");
	Power = setup("_pwr_clr");
	Sema = setup("_seminfo");
	Messag = setup("_msginfo");
#ifdef vax
	Shmem = setup("_shminfo");
#endif
#ifdef pdp11
	Maus = setup("_mausmap");
#endif
	X25 = setup("_x25info");
	pre[0] = '_';

	while(fgets(line, 256, mast) != NULL) {
		if(line[0] == '*')
			continue;
		if(line[0] == '$')
			break;
		if (sscanf(line, "%s %d %d %o %s %d %o %d %d %d ",
			nm,&vsz,&x,&typ,&pre[1],&x,&x,&x,&deft,&bus,&x) != 10)
			continue;
		if(!strcmp(nm, "memory") || !strcmp(nm, "tty"))
			continue;
		strcpy(intrnm, pre);
		strcpy(devaddr, pre);
		strcpy(devcnt, pre);
		strcat(devaddr, "_addr");	/* _pre_addr */
		strcat(devcnt, "_cnt");	/* _pre_cnt */
		switch(vsz) {
			case 8: strcat(intrnm, "rint"); break;
			case 1: /* massbus devices */
			case 4: strcat(intrnm, "intr"); break;
			case 0: break; /* pseudo devices */
			default: continue;
		}
		setln(nm, setup(intrnm), vsz, deft, typ & BLOCK, bus);
		setup(devaddr);
		setup(devcnt);
		if(typ & BLOCK) {
			strcpy(strat, pre);
			strcat(strat, "strategy");
			setup(strat);
		}
	}
	endnm = setup("");
	endln = lnptr;
	nlist(os, nl);

#ifdef	DEBUG
/*
*	Print out the namelist
*/
	for(lnptr=ln; lnptr != endln; ++lnptr) {
		printf(NBPW==4 ? "%s\t%o\t%x\n" : "%s\t%o\t%o\n" ,
			(lnptr->l_nptr[INTR]).n_name,
			(lnptr->l_nptr[CNT]).n_type,
			(lnptr->l_nptr[CNT]).n_value);
		printf(NBPW==4 ? "%s\t%o\t%x\n" : "%s\t%o\t%o\n" ,
			(lnptr->l_nptr[ADDR]).n_name,
			(lnptr->l_nptr[ADDR]).n_type,
			(lnptr->l_nptr[ADDR]).n_value);
	}
#endif

	fseek(system, (long) SYM_VALUE(bdevcnt) - offset, 0);
	fread(&bcnt, INTSZ, 1, system);
	fseek(system, (long) SYM_VALUE(mbacnt) - offset, 0);
	fread(&mcnt, INTSZ, 1, system);
	fseek(system, (long) SYM_VALUE(rootdev) - offset, 0);
	fread(&root, INTSZ, 1, system);
	fseek(system, (long) SYM_VALUE(pipedev) - offset, 0);
	fread(&pipe, INTSZ, 1, system);
	fseek(system, (long) SYM_VALUE(swapdev) - offset, 0);
	fread(&swap, INTSZ, 1, system);
	fseek(system, (long) SYM_VALUE(dumpdev) - offset, 0);
	fread(&dump, INTSZ, 1, system);
	fseek(system, (long) SYM_VALUE(Power) - offset, 0);
	fread(&power, INTSZ, 1, system);
	fseek(system, (long) SYM_VALUE(Maus) - offset, 0);
	fread(&maus, INTSZ, 1, system);

#ifdef	vax
	vaxdevs();
#else
	pdpdevs();
#endif

	printf("*\n* Pseudo Devices\n*\n");
	pseudo_devs();

	/* rootdev, swapdev, pipedev, dumpdev, power */

	printf("*\n* System Devices\n*\n");

	if((lnptr = majsrch((root >> 8) & 0377)) == NULL)
		fprintf(stderr, "unknown root device\n");
	else
		printf("root\t%s\t%o\n", lnptr->l_cfnm, root & 0377);

	if((lnptr = majsrch((swap >> 8) & 0377)) == NULL)
		fprintf(stderr, "unknown swap device\n");
	else {
		printf("swap\t%s\t%o\t", lnptr->l_cfnm, swap & 0377);
		fseek(system, (long) SYM_VALUE(swplo) - offset, 0);
		fread(&swap_low, 4, 1, system);
		fseek(system, (long) SYM_VALUE(nswap) - offset, 0);
		fread(&n_swap, 2, 1, system);
		printf("%ld\t%d\n", swap_low, n_swap);
	}

	if((lnptr = majsrch((pipe >> 8) & 0377)) == NULL)
		fprintf(stderr, "unknown pipe device\n");
	else
		printf("pipe\t%s\t%o\n", lnptr->l_cfnm, pipe & 0377);

	if((lnptr = majsrch((dump >> 8) & 0377)) == NULL)
		fprintf(stderr, "unknown dump device\n");
	else
		printf("dump\t%s\t%o\n", lnptr->l_cfnm, dump & 0377);

	/* easy stuff */

	nlptr = nl;
	vs = setup("_v");
	smap = setup("_swapmap");
	callo = setup("_callout");
	endnm = setup("");
	nlist(os, nl);
	for(nlptr = vs; nlptr != endnm; nlptr++) {
#ifdef vax
		if(nlptr->n_value == 0) {
#else
		if(nlptr->n_type == 0) {
#endif
			fprintf(stderr, "namelist error\n");
			exit(1);
		}
	}
	fseek(system, (long) SYM_VALUE(vs) - offset, 0);
	fread(&v, sizeof v, 1, system);
	printf("*\n* Tunable Parameters\n*\n");
	printf("buffers\t%11d\n", v.v_buf);
	printf("calls\t%11d\n", v.v_call);
	printf("inodes\t%11d\n", v.v_inode);
	printf("files\t%11d\n", v.v_file);
	printf("mounts\t%11d\n", v.v_mount);
	printf("procs\t%11d\n", v.v_proc);
	printf("texts\t%11d\n", v.v_text);
	printf("clists\t%11d\n", v.v_clist);
	printf("sabufs\t%11d\n", v.v_sabuf);
	printf("maxproc\t%11d\n", v.v_maxup);
#ifdef	pdp11
	printf("coremap\t%11d\n", v.v_cmap);
#endif
	printf("swapmap\t%11d\n", v.v_smap);
	printf("hashbuf\t%11d\n", v.v_hbuf);
	printf("physbuf\t%11d\n", v.v_pbuf);
#ifdef	pdp11
	printf("iblocks\t%11d\n", v.v_iblk);
#endif
	if(X25->n_value != 0) {
		fseek(system, (long) SYM_VALUE(X25) - offset, 0);
		fread(&x25info, sizeof(x25info), 1, system);
		printf("x25links%11d\n", x25info.x25links);
		printf("x25bufs\t%11d\n", x25info.x25bufs);
		printf("x25bytes  (%d*1024)\n",(x25info.x25bytes/1024));
	}
	printf("power\t%11d\n", power ? 1 : 0);
	printf("mesg\t%11d\n", Messag->n_value ? 1 : 0);
	printf("sema\t%11d\n", Sema->n_value ? 1 : 0);
#ifdef vax
	printf("shmem\t%11d\n", Shmem->n_value ? 1 : 0);
#endif
#ifdef	pdp11
	printf("maus\t%11d\n", (maus != -1) ? 1 : 0);
#endif
	exit(0);
}

/*
 * setup - add an entry to a namelist structure array
 */
struct	nlist	*
setup(nam)
	char	*nam;
{
	if(nlptr >= &nl[MAXI]) {
		fprintf(stderr, "internal name list overflow\n");
		exit(1);
	}
	strncpy(nlptr->n_name, nam, 8);
	nlptr->n_type = 0;
	nlptr->n_value = 0;
	return(nlptr++);
}

/*
 * setln - set up internal link structure for later
 * function look-up.  Records useful information from the
 * /etc/master table description.
 */
struct	link	*
setln(cf, np, vz, dft, dt, br)
	char	*cf;
	struct	nlist	*np;
	int	vz;
	int	dft;
	int	dt;
	int	br;
{
	if(lnptr >= &ln[MAXI/3]) {
		fprintf(stderr, "internal link array overflow\n");
		exit(1);
	}
	strcpy(lnptr->l_cfnm, cf);
	lnptr->l_nptr = np;
	lnptr->l_vsz = vz;
	lnptr->l_def = dft;
	lnptr->l_dtype = dt;
	lnptr->l_bus = br;
	return(lnptr++);
}

/*
 * search - search for a function indirectly through
 * the link structure.
 */
struct	link	*
search(vctr,sub)
#ifdef	vax
	int	vctr;
#else
	struct	interface	*vctr;
#endif
	int	sub;
{
	register struct	link	*lnkptr;
#ifdef pdp11
	struct xinterface xi;
	long	off;
#endif

	for(lnkptr = ln; lnkptr != endln; lnkptr++) {
#ifdef	vax
#ifdef	DEBUG
printf("link val=%x vctr=%x\n",(lnkptr->l_nptr[sub]).n_value, (vctr & ~D7));
#endif
		if((lnkptr->l_nptr[sub]).n_value == (vctr & ~D7)) {
#else
#ifdef	DEBUG
printf("link val=%o vctr=%o\n",(lnkptr->l_nptr[sub]).n_value, vctr->i_func);
#endif
		if((lnkptr->l_nptr[sub]).n_value == (unsigned)vctr->i_func) {
#endif
			lnkptr->l_used = (char)1;
			return(lnkptr);
		}
	}
#ifdef pdp11
       /*
	* if overlay-loaded system, use interface table address to follow
	* chain into overlay segments and give search a second chance.
	*/
	if (ovly) {
#ifdef DEBUG
		printf("in overlay search\n");
#endif
		off = (unsigned) vctr->i_func;
		fseek(system, off + TXT, 0);
		fread(&xi, sizeof(xi), 1, system);
		for(lnkptr = ln; lnkptr != endln; lnkptr++) {
#ifdef	DEBUG
printf("link val=%o vctr=%o\n",(lnkptr->l_nptr[sub]).n_value, xi.i_func);
#endif
			if((lnkptr->l_nptr[sub]).n_value == (unsigned)xi.i_func-4) {
				lnkptr->l_used = (char)1;
				return(lnkptr);
			}
		}
	}
#endif
	return(NULL);
}

/*
 * majsrch - search for a link structure given the major
 * device number of the device in question.
 */
struct	link *
majsrch(maj)
	int	maj;
{
	register struct	link	*lnkptr;
#ifdef pdp11
	struct xinterface	xi;
	long	off;
#endif

	if(maj > bcnt - 1)
		return(NULL);

	fseek(system,(long)SYM_VALUE(bdevsw)+(maj*sizeof(bent))-offset,0);
	fread(&bent, sizeof bent, 1, system);

	for(lnkptr = ln; lnkptr != endln; lnkptr++)
		if(lnkptr->l_dtype) {
#ifdef	DEBUG
#ifdef	pdp11
printf("link val=%o bent=%o\n",(lnkptr->l_nptr[STRAT]).n_value, bent.b_strategy);
#endif
#ifdef	vax
printf("link val=%x vctr=%x\n",(lnkptr->l_nptr[STRAT]).n_value, bent.b_strategy);
#endif
#endif
			if((lnkptr->l_nptr[STRAT]).n_value == bent.b_strategy)
				return(lnkptr);
		}
#ifdef pdp11
       /*
	* if overlay-loaded system, use interface table address to follow
	* chain into overlay segments and give search a second chance.
	*/
	if (ovly) {
#ifdef DEBUG
		printf("in overlay search\n");
#endif
		off = (unsigned) bent.b_strategy;
		fseek(system, off + TXT, 0);
		fread(&xi, sizeof(xi), 1, system);
		for(lnkptr = ln; lnkptr != endln; lnkptr++) {
#ifdef	DEBUG
printf("link val=%o vctr=%o\n",(lnkptr->l_nptr[STRAT]).n_value, xi.i_func);
#endif
			if((lnkptr->l_nptr[STRAT]).n_value == (unsigned)xi.i_func-4) {
				lnkptr->l_used = (char)1;
				return(lnkptr);
			}
		}
	}
#endif
	return(NULL);
}

#ifdef vax
vaxdevs()
{
	register int i;
	if(UNIvec->n_value == 0) {
		fprintf(stderr, "%s %s\n", "symbol \"UNIvec\" undefined; ",
			"invalid /unix file");
		exit(1);
	}
	if(Mbacf->n_scnum == 0) {
		fprintf(stderr, "%s %s\n", "symbol \"_mbacf\" undefined; ",
			"invalid /unix file");
		exit(1);
	}

	printf("*\n* MASSBUS\n* dev\tnexus\taddr\tbus\n*\n");

/* MASSBUS devices from _mbacf */
	if(fseek(system, (long)SYM_VALUE(Mbacf) - offset, 0) != NULL) {
		fprintf(stderr, "sysdef: seek failed on %s\n",system);
		exit(1);
	}

	for(i=0; i < mcnt; ++i) {
		fread(&mbadev, sizeof mbadev, 1, system);
		if(mbadev.nexus == NULL) continue;
		if((lnptr = search(mbadev.dev_addr,ADDR)) == NULL) {
			fprintf(stderr,
				"unknown device at NEXUS %3d\n", mbadev.nexus);
			continue;
		}

		printf("%s\t%3d\t%d\t%d",
			lnptr->l_cfnm,mbadev.nexus,0,mbadev.bus_req);
		printf("\n");
	}

	if(fseek(system, (long)SYM_VALUE(UNIvec) - offset, 0) != NULL) {
		fprintf(stderr, "sysdef: seek failed on %s\n",system);
		exit(1);
	}

/* on a VAX the following works only for UNIBUS devices */

	printf("*\n* UNIBUS\n* dev\tvector\taddr\tbus\tcount\n*\n");

	for(vec=0; vec < (int *)(INTSZ * 128); ++vec) {
		fread(&vector, sizeof vector, 1, system);
		if(vector.vaxvec == NULL) continue;
		if((lnptr = search(vector.vaxvec,INTR)) == NULL) {
			fprintf(stderr,"unknown device at vector %3o\n", vec);
			continue;
		}
		printf("%s\t%3o", lnptr->l_cfnm, vec);
		unit = (vector.vaxvec & D7) >> 27;
		if(fseek(sysseek,
			(long)(((lnptr->l_nptr[ADDR]).n_value & USRMASK)
			- ftell(sysseek) + (INTSZ * unit) - offset), 1) != NULL) {
			fprintf(stderr,"bad seek for device address\n");
		}
		if(fread(&address, sizeof(address), 1, sysseek) != 1) {
			fprintf(stderr,"cannot read dev_addr\n");
		}

		printf("\t%lo\t%1o",(address), lnptr->l_bus);

		fseek(sysseek, (long)(lnptr->l_nptr[CNT].n_value & USRMASK)
			- ftell(sysseek) - offset, 1);
		fread(&count, INTSZ, 1, sysseek);
		if((unit + 1) * lnptr->l_def > count)
			printf("\t%d", count % lnptr->l_def);
		else
			printf("\t%d", lnptr->l_def);
		printf("\n");

		if(lnptr->l_vsz == 8) {
			vec++;
			fread(&vector, sizeof vector, 1, system);
		}
	}
}
#endif

#ifdef	pdp11
pdpdevs()
{
	register int i;
	if(start->n_type == 0) {
		fprintf(stderr, "%s %s\n",
			"symbol \"start\" undefined; ",
			"invalid /unix file");
		exit(1);
	}
	if(restart->n_value) {
		IFC = 01020;
		IFC_SZ = sizeof(xifc[0]);
		if((start->n_value - IFC) > (MAXI / 3 * (sizeof ifc[0]))) {
			printf("internal interface array overflow\n");
			exit(1);
		}
		fseek(system, (long) IFC + TXT, 0);
		fread(xifc, sizeof xifc[0], N_IFC, system);
		for(i=0; i < N_IFC; ++i) {
			ifc[i].i_jsr = xifc[i].i_jsr;
			ifc[i].i_call = xifc[i].i_call;
			ifc[i].i_func = (xifc[i].i_func + IFC + 
				( i + 1) * 8);
		}
	}
	else {
		if((start->n_value - IFC) > (MAXI / 3 * (sizeof ifc[0]))) {
			fprintf(stderr, "internal interface array overflow\n");
			exit(1);
		}
		fseek(system, (long) IFC - offset, 0);
		fread(ifc, sizeof ifc[0], (start->n_value - IFC) /
			sizeof ifc[0], system);
	}

	printf("*\n* dev\tvector\taddr\tbus\tcount\n*\n");
	for(addr = (struct vector *)0; addr != (struct vector *)01000; addr++) {
		if(addr == (struct vector *)060)
			addr = (struct vector *)070;	/* skips console */
		fseek(system, (long)addr - offset, 0);
		fread(&vector, sizeof vector, 1, system);
		if((vector.v_pc <= IFC) || (vector.v_pc >= start->n_value))
			continue;	/* skips clio, traps, jmp, etc */
		if((lnptr = search(&ifc[(vector.v_pc - IFC) / IFC_SZ],INTR))
			== NULL) {
			fprintf(stderr,
				"unknown device interrupts at vector %3o\n",
				addr);
			continue;
		}
		printf("%s\t%3o", lnptr->l_cfnm, addr);
		unit = vector.v_psw & CC;
		bus = (vector.v_psw & BUS) >> 5;
		fseek(system,(long)(lnptr->l_nptr[ADDR].n_value+2*unit-offset),0);
		fread(&address, 2, 1, system);
		printf("\t%6o\t%1o", address, bus);
		fseek(system, (long)(lnptr->l_nptr[CNT].n_value - offset), 0);
		fread(&count, NBPW, 1, system);
		if((unit + 1) * lnptr->l_def > count)
			printf("\t%d", count % lnptr->l_def);
		else
			printf("\t%d", lnptr->l_def);
		printf("\n");
		if(lnptr->l_vsz == 8)
			addr++;
	}
}
#endif

pseudo_devs()
{
	register struct link	*lnkptr;
	int			count;

	for(lnkptr = ln; lnkptr != endln; lnkptr++) {
		if( ! (lnkptr->l_nptr[CNT]).n_value) {  /* dev_cnt undefined*/
			continue;
		}
		if(lnkptr->l_used) {	/*has already been printed*/
			continue;
		}
		if(strcmp(lnkptr->l_cfnm,"dl11") == 0) { /* /dev/console */
			continue;
		}

		fseek(system, (long)
			((lnkptr->l_nptr[CNT]).n_value & USRMASK) - offset, 0);
		fread(&count, INTSZ, 1, system);
		printf("%s\t%d\t%d\t%d\t%d\n",lnkptr->l_cfnm,0,0,0,count);
	}
}