File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / d / ioex / multi.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:24:19 2019 UTC (6 years, 11 months ago) by root
Branches: bsd, MAIN
CVS tags: v12b, v121, HEAD
Power 6/32 Unix version 1.2b


#include "vddc.h"
#define GATE_CLOSED	(0xff)	
#define NBPG	1024
asm(".set NBPG,1024");
asm(".set IPL,0x8");

struct ccb	/* CHANNEL CONTROL BLOCK */
{
  char ccw ;		/* 0x11 normal; 0x09 clear non_vect interrupt */
  char gate;		/* This is "the" GATE */
  char pt_tpb[4] ;	/* pointer to ->TAPE OPERATION BLOCK or MOVE BLOCK */
};
extern long Probe, iob0, iob1, iob2, iob3, iob4;
extern long Multi, cmd_done, Vdone;
extern long tape_ON, vddc_ON, vioc_ON;

extern struct DEVPAR devpar[];
extern struct tpb tpb;
extern struct ccb ccblk;
extern struct DCB vdcb;
extern struct tpblk *tblk;

long disk_buf[2*NBPG/4];
long mul_err = 0;


multi()
{
	register long tm_bsiz, drno;

	writes("\n\t** Multiple interrupts test **\n");
	drno = get_unit();
	if (tape_ON) {
		tm_bsiz = tape_op(CONFIG,0,0);
		tm_rew(); 		/* rewind tape */
		tblk = (struct tpblk *)&tpb;
		}
	mul_err = 0;
	multi_ex(&iob0, &iob2, &iob4, disk_buf, drno);
	if (!mul_err) writes("\nPassed..\n");
		else writes("\nFailed..\n");
}


/*	This test tries by create memory contention between Tahoe
	and the tape master by the following actions :
		(1) Sent a command to Tape master to move 2 blocks
		    of data in Tahoe memory to buffer X, X+1
		(2) use movblk instruction to move the same 2 blocks
		    to buffer Y, Y+1 and keep doing this until cmd_done
		    (indicate tape master done with command)
		(3) compare buffer X, X+1 with Y, Y+1.
*/
multi_ex(srcbuf, tdest, sdest, dbuff,drno)
char *srcbuf, *tdest, *sdest, *dbuff;
long drno;
{	register long ix, *lptr;
	register short *sptr;

	sptr = (short *)srcbuf;		/* Write pattern to source buffers */
	for (ix=0; ix<NBPG; ix++) *sptr++ = ix; 
	for (ix=0; ix<(NBPG*2); ix++)  {
		sdest[ix] = tdest[ix] = dbuff[ix] = 0;	/* Clear destination */
		}

	/* Set up Tpb to move 2 blocks */
	if (tape_ON) tblk_mv(srcbuf,tdest,NBPG*2);	
	mul_int(srcbuf,sdest,drno,dbuff);

	for (ix=0; ix<(NBPG*2); ix++) {
		if (tape_ON) {
			if (srcbuf[ix] != tdest[ix]) {
				writes("\nBlockmv tape error, expected ");
				writeh(srcbuf[ix]&0xff);
				writes(" , actual "); writeh(tdest[ix]&0xff);
				writes(" , address "); writeh(&tdest[ix]);
				mul_err = 1;
				}
			}
		if (vddc_ON) {
			if (srcbuf[ix] != dbuff[ix]) {
				writes("\nBlockmv disk error, expected ");
				writeh(srcbuf[ix]&0xff);
				writes(" , actual "); writeh(dbuff[ix]&0xff);
				writes(" , address "); writeh(&dbuff[ix]);
				mul_err = 1;
				}
			}
		if (srcbuf[ix] != sdest[ix]) {
			writes("\nBlockmv Tahoe error, expected ");
			writeh(srcbuf[ix]&0xff);
			writes(" , actual "); writeh(sdest[ix]&0xff);
			writes(" , address "); writeh(&sdest[ix]);
			mul_err = 1;
			}
		}
}


get_unit()
{	register long unit;
	for (unit=0;devpar[unit].nocyl;unit++) 
		{ if (devpar[unit].alive) return(unit); }
	return(-1);
}


/*	Routine to create memory contention
	return -1 if error
*/
mul_int(src,sdest,dno,dbuff)
char *src, *sdest, *dbuff;
long dno;
{	register long *r12, cntr, rtn_cnt, ix, save;

	Multi = 1;
	if (tape_ON) get_taperdy();	/* Get Tape ready */
	cmd_done = 0;

	asm("mtpr $0x1f,$IPL");		/* NO interrupt yet ! */
	if (vddc_ON) vddc_op(WR_COMP,dno,0x2025a,2,src);
	if (tape_ON) cy_attn();		/* Execute command */

	for (ix=0;ix<6;ix++) {	/* Burns some time,TAHOE do some block move */
		asm("movl 4(fp),r0");		/* Source */
		asm("movl 8(fp),r1");		/* Destination */
		asm("movl $NBPG*2,r2");		/* Count */
		asm("movblk");			/* Move it */
		}
	ix =1;
	asm("mtpr $0x1,$IPL");		/* NOW interrupt me.. */
	if (tape_ON)  {
		if (!isvddc_done()) return(-1);
		if (cmd_done == 2) return(-1); 	/* operation has error */	
		}
	if (vddc_ON) {
		while (!Vdone);
		Multi = 0;
		vddc_op(RD_DATA,dno,0x2025a,2,dbuff);
		}
	Multi = 0;
	return(0);
}

isvddc_done()
{	register long count;
	count = 400;
	while (!cmd_done)	{
		DELAY(0x1fffff);
		if (--count==0) return(0);
		}
	return(1);
}

get_taperdy()
{
	while (g_open()==0)			/* Is gate open ? */
		{ tm_init();
		error("tape not ready yet..\n");
		return(-1);
		}
	ccblk.gate = (char)GATE_CLOSED;		/* Close gate */
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.