File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / sys / vba / dr11.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:30:09 2019 UTC (7 years ago) by root
Branches: bsd, MAIN
CVS tags: v121, HEAD
Power 6/32 Unix version 1.21

#include "dr.h"
#if NDR > 0

/*      DRV11-W DMA interface driver utility
 *
 */

#include "../machine/pte.h"
#include "../machine/mtpr.h"
#include "../h/param.h"
#include "../h/conf.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/proc.h"
#include "../h/map.h"
#include "../h/ioctl.h"
#include "../h/buf.h"
#include "../h/vm.h"
#include "../h/uio.h"

#include "../vba/vbavar.h"
#include "../h/drreg.h"

extern struct  vba_device  *drinfo[];
extern struct  dr_aux dr_aux[];

#define YES 1
#define NO  0

#define RSUNIT(dev) (minor(dev) & 7)

#define SPL_UP spl8

/* -------- Per-unit data -------- */

extern struct dr_aux dr_aux[];
extern struct vba_device *drinfo[];

dr11open (dev, flag)
dev_t dev;
int flag;
{
    if (!(suser())) return(EPERM);
    return 0;
}

dr11close (dev)
dev_t dev;
{
    return;
}


dr11ioctl(dev, cmd, data, flag)
dev_t dev;
int cmd;
struct dr11io *data;
int flag;
{
    register int unit = data->arg[0];
    register struct dr_aux *dra;
    register struct rsdevice *rsaddr;
    struct dr11io dio;
    ushort temp, s, errcode, status;

    dra = &dr_aux[unit];
    if (!(dra->dr_flags & DR_PRES)) return(ENODEV);
    rsaddr = RSADDR(unit);
    switch (cmd) {

    case DR11STAT:
    	/* Copy back dr11 status to user */
    	data->arg[0] = dra->dr_flags;
    	data->arg[1] = rsaddr->dr_cstat;
    	data->arg[2] = dra->dr_istat;	/* Status reg. at last interrupt */
    	data->arg[3] = rsaddr->dr_data;	/* P-i/o input data */
    	status = (ushort)((rsaddr->dr_addmod << 8) & 0xff00);
    	data->arg[4] = status | (ushort)(rsaddr->dr_intvect & 0xff);
    	data->arg[5] = rsaddr->dr_range;
    	data->arg[6] = rsaddr->dr_rahi;
    	data->arg[7] = rsaddr->dr_ralo;
	break;
    case DR11LOOP:
	/* Perform loopback test -- MUST HAVE LOOPBACK CABLE ATTACHED --
	   Test results are printed on system console */
	dr11loop(rsaddr,dra,unit);
	break;

    default:
	break;
    }

#ifdef DR_DEBUG
/*
  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
printf("\n\t------------- DR11 Status ------------");
printf("\n\t  dr_flags  CSR   istat  idata  modvec  dmacnt  hiadr  loadr");
printf("\n\t    %lx    %lx  %lx   %lx   %lx    %ld   %lx   %lx\n",
	data->arg[0],data->arg[1],data->arg[2],data->arg[3] & 0xffff,
	data->arg[4],data->arg[5],data->arg[6],data->arg[7]);
   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
#endif

    return 0;
}

#define NPAT 2
#define DMATBL 20
ushort tstpat[DMATBL] = { 0xAAAA, 0x5555};
long DMAin = 0;

dr11loop(dr,dra,unit)
struct rsdevice *dr;
struct dr_aux *dra;
long unit;
{	register long result, ix;
	long baddr, wait;

	dr->dr_cstat = MCLR;		/* Clear board & device, disable intr */

	/* Perform loopback test -- MUST HAVE LOOPBACK CABLE ATTACHED --
	   Test results are printed on system console */
	printf("\n\t ----- DR11 unit %ld loopback test -----",unit);

	printf("\n\t Program I/O ...");
	for (ix=0;ix<NPAT;ix++) {
		dr->dr_data = tstpat[ix];	/* Write to Data out register */
		result = (dr->dr_data & 0xFFFF);	/* Read it back */
		if (result != tstpat[ix]) {
			printf("Failed, expected : %lx --- actual : %lx",
				tstpat[ix],result);
			return;
		}
	}

	printf("OK\n\t Functions & Status Bits ...");
	dr->dr_cstat = (FCN1 | FCN3);
	result = dr->dr_cstat & 0xffff;		/* Read them back */
	if ((result & (STTC | STTA)) != (STTC |STTA)) {
		printf("Failed, expected : %lx --- actual : %lx, ISR:%lx",
			(STTA|STTC),(result & (STTA|STTC)), result);
		return;
	}
	dr->dr_cstat = FCN2;
	result = dr->dr_cstat & 0xffff;		/* Read them back */
	if ((result & STTB) != STTB) {
		printf("Failed, expected : %lx --- actual : %lx, ISR:%lx",
			STTB,(result & STTB), result);
		return;
	}

	printf("OK\n\t DMA output ...");

	if (DMAin) goto dmain;

	/* Initialize DMA data buffer */
	for(ix=0;ix<DMATBL;ix++) tstpat[ix] = 0xCCCC + ix;
	tstpat[DMATBL-1] = 0xCCCC;	/* Last word output */

	/* Setup normal DMA */
	baddr = (long)vtoph(0,tstpat);		/* Virtual --> physical */
    	dr->dr_walo = (ushort)((baddr >> 1) & 0xffff);
    	dr->dr_wahi = (ushort)((baddr >> 17) & 0x7fff);

    	/* Set DMA range count: (number of words - 1) */
    	dr->dr_range = (ushort)(DMATBL - 1);

    	/* Set  address modifier code to be used for DMA access to memory */
    	dr->dr_addmod = (char)DRADDMOD;

    	/* Clear dmaf and attf to assure a clean dma start, also disable
	   attention interrupt
	*/
    	dr->dr_pulse = (ushort)(RDMA|RATN|RMSK);  /* Use pulse register */
    	dr->dr_cstat = (GO|CYCL);		  /* GO...... */

	/* Wait for DMA complete; REDY and DMAF are true in ISR */
	wait = 0;
	while ((result=(dr->dr_cstat & (REDY | DMAF))) != (REDY|DMAF)) {
		printf("\n\tWait for DMA complete...ISR : %lx",result);
		if (++wait > 5) {
			printf("\n\t DMA output fails...timeout!!, ISR:%lx",
				result);
			return;
		}
	}

	result = dr->dr_data & 0xffff;		/* Read last word output */	
	if (result != 0xCCCC) {
		printf("\n\t Fails, expected : %lx --- actual : %lx",
			0xCCCC,result);
		return;
	}

	printf("OK\n\t DMA input ...");

dmain:
	dr->dr_data = 0x1111;		/* DMA input data */
	/* Setup normal DMA */
	baddr = (long)vtoph(0,tstpat);		/* Virtual --> physical */
    	dr->dr_walo = (ushort)((baddr >> 1) & 0xffff);
    	dr->dr_wahi = (ushort)((baddr >> 17) & 0x7fff);

    	/* Set DMA range count: (number of words - 1) */
    	dr->dr_range = (ushort)(DMATBL - 1);

    	/* Set  address modifier code to be used for DMA access to memory */
    	dr->dr_addmod = (char)DRADDMOD;
	/* Set FCN1 in ICR to DMA in*/
	dr->dr_cstat = FCN1;

	if (!(dra->dr_flags & DR_LOOPTST)) {
		/* Use pulse reg */  
    		dr->dr_pulse = (ushort)(RDMA|RATN|RMSK|CYCL|GO);
		/* Wait for DMA complete; REDY and DMAF are true in ISR */
		wait = 0;
		while ((result=(dr->dr_cstat & (REDY | DMAF))) 
						!= (REDY|DMAF)) {
			printf("\n\tWait for DMA to complete...ISR:%lx",result);
			if (++wait > 5) {
				printf("\n\t DMA input timeout!!, ISR:%lx",
					result);
				return;
			}
		}
	}
	else  {
		/* Enable DMA e-o-r interrupt */
    		dr->dr_pulse = (ushort)(IENB|RDMA|RATN|CYCL|GO);
		/* Wait for DMA complete; DR_LOOPTST is false in dra->dr_flags*/
		wait = 0;
		while (dra->dr_flags & DR_LOOPTST) { 
			result = dr->dr_cstat & 0xffff;
			printf("\n\tWait for DMA e-o-r intr...ISR:%lx",result);
			if (++wait > 7) {
				printf("\n\t DMA e-o-r timeout!!, ISR:%lx",
					result);
				dra->dr_flags &= ~DR_LOOPTST;
				return;
			}
		}
		dra->dr_flags |= DR_LOOPTST;
	}

	mtpr(tstpat,P1DC);			/* Purge cache */
	mtpr((0x3ff+(long)tstpat),P1DC);
	for(ix=0;ix<DMATBL;ix++) {
		if (tstpat[ix] != 0x1111) {
			printf("\n\t Fails, ix:%ld,expected : %lx --- actual : %lx",
				ix,0x1111,tstpat[ix]);
			return;
		}
	}
	if (!(dra->dr_flags & DR_LOOPTST)) {
		dra->dr_flags |= DR_LOOPTST;
		printf(" OK..\n\tDMA end of range interrupt...");
		goto dmain;
	}


	printf(" OK..\n\tAttention interrupt....");
	/* Pulse FCN2 in pulse register with IENB */
    	dr->dr_pulse = (ushort)(IENB|RDMA);
    	dr->dr_pulse = (ushort)FCN2;

	/* Wait for ATTN interrupt; DR_LOOPTST is false in dra->dr_flags*/
	wait = 0;
	while (dra->dr_flags & DR_LOOPTST) { 
		result = dr->dr_cstat & 0xffff;
		printf("\n\tWait for Attention intr...ISR:%lx",result);
		if (++wait > 7) {
			printf("\n\t Attention interrupt timeout!!, ISR:%lx",
				result);
			dra->dr_flags &= ~DR_LOOPTST;
			return;
		}
	}
	dra->dr_flags &= ~DR_LOOPTST;
	printf(" OK..\n\tDone...");
}

#endif

unix.superglobalmegacorp.com

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