|
|
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 */
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.