⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gq.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
     * Although some test runs (heavy imaging) shows this to be true, and     * in some cases very true, it shouldn't be.  There must be a race     * condition we're not handling somewhere... I do know of 1 created by     * the pre-pagein code.     */    pte = vtopte(gx_serverp, btop(tmpVA));    if (pte && pte->pg_v) {	*GQ_INTRH(gqo) = 0;		/* clr intr */	wbflush();			/* n10 will retry */	if ((va & HST_INTR_DRTY) == 0)	    pte->pg_m = 1;		/* mark dirty */	return 0;    }#   endif    return _gq_intr_pagein(va);}/* end gq_intr_pagein. */gq_intr_xlate(va)    int va;{    register int tmpVA, vsn;    register struct pte *pte;    tmpVA = (va & HST_INTR_MASK);    vsn = vtovsn(tmpVA);		/* virt seg num */    GX_DEBUG(GX_BLAB,	     gx_printf("xlate: vpn 0x%x vsn 0x%x\n", btop(tmpVA), vsn);	     );    pte = vtopte(gx_serverp, btop(tmpVA));    GX_DEBUG(GX_GAB,	     gx_printf("xlate: sp 0x%x (0x%x+0x%x) pte 0x%x\n",		       gx_serverp,		       gx_serverp->p_datastart,		       gx_serverp->p_dsize,		       pte);	     );    if (pte == 0) {	/*GQ_INTRH(gqo) = va;		/* clear intr line */	/*wbflush();*/	printf("gq_intr_xlate: bad VA 0x%x\n", tmpVA);	/* let server segv while handling signal */	return _gq_intr_pagein(va);    }    gq_ptpt[vsn] = (int) svtophy((int)pte & ~(NBPG-1)) | vsn;    GX_DEBUG(GX_GAB,	     gx_printf("gq_intr_xlate(va=0x%x) -> ptpt[0x%x]=0x%x\n",		       tmpVA, vsn, gq_ptpt[vsn]);	     );    if (pte->pg_v)    {	/* page is already valid */	*GQ_INTRH(gqo) = (pte->pg_pfnum << GQ_INTR_SHFT);	wbflush();	return 0;    }    else    {	/* request pagein */	return _gq_intr_pagein(va);    }}/* end gq_intr_xlate. */gq_intr_vrfy(va)    int va;{    register int tmpVA;    register struct pte *pte;    tmpVA = (va & HST_INTR_MASK);    pte = vtopte(gx_serverp, btop(tmpVA));    if (pte == 0) {	/*GQ_INTRH(gqo) = va;		/* clear intr line */	/*wbflush();*/	printf("gq_intr_vrfy: bad VA 0x%x\n", tmpVA);	/* let server segv while handling signal */	return _gq_intr_pagein(va);    }    if (pte->pg_v)    {	/* page is already valid */	*GQ_INTRH(gqo) = (pte->pg_pfnum << GQ_INTR_SHFT);	wbflush();	return 0;    }    else    {	*GQ_INTRH(gqo) = GQ_INTR_ACK;	/* N10 will choke on this */	wbflush();	GX_DEBUG(GX_CONSOLE,		 gq_thrash++;		 gx_printf("gq_intr_vrfy: bad pte 0x%x (VA 0x%x)\n",			   pte, tmpVA);		 );	gx_serverp->p_dev_VM_maint = 0;	psignal(gx_serverp, SIGSEGV); /* not valid - SEGV the server */    }}/* end gq_intr_vrfy. *//****************************************************************** **                                                              ** ** Graphics device end-of-frame interrupt service routine.      ** **                                                              ** ****************************************************************** * * For the HE3D 3MAX board, N10 receives VINT.  VINT is normally off. * When an N10 packet with the sync bit arrives at the head of the * packet queue, N10 enables VINT and interrupts R3 when STIC interrupts * N10 for VINT.  We load the colormap during this time.  Unused. */gq_intr_vblank(va)    int va;{    *GQ_INTRH(gqo) = GQ_INTR_ACK;    wbflush();    GX_DEBUG(GX_BLAB,	     gx_puts("gq_intr_vblank()\n");	     );    gx_load_colormap();    gxp->qe.timestamp_ms = TOY;    return 0;}/* end gq_intr_vblank. */int gq_intr_total = 0;gqintr(unit)    register int unit;{    gq_intr_total++;    if (GX_HAVESERVER)    {	int intr_cause = GQ_RAM(gqo)->intr_host;	/* XXX byte-0 assumed. */	(gq_intr_recv[intr_cause & HST_INTR_WHAT])++;	return (*gq_intr_vec[intr_cause & HST_INTR_WHAT])(intr_cause);    }    else    {	/* could also be a STIC error intr... */	return gq_intr_stic();    }}/* end gqintr. */gq_intr_coproc(cmd)    int cmd;{    register int i, ans;    volatile int *intr_coproc = GQ_INTRC(gqo);    volatile int *read_coproc = &(GQ_RAM(gqo)->intr_coproc);    int rval = 4;    int timo = gq_N1OK ? GQ_INTR_TIMO : (GQ_INTR_TIMO >> 2);    GX_DEBUG(GX_SILENT,	     if (gq_intrPending) {		 /* nested interrupts invalid */		 printf("gq_intr_coproc: new 0x%x (old 0x%x)\n",			cmd, *read_coproc);		 panic("gq_intr_coproc: nested\n");	     }	     gq_intrPending = 1;	     );    GX_DEBUG(GX_NEVER,	     gx_printf("gq_intr_coproc(cmd=0x%x)\n", cmd);	     );    *intr_coproc = cmd;    wbflush();    gq_intr_send[(cmd & GQ_INTR_WHAT) >> GQ_INTR_WSHF]++;    for ( i = timo; i > 0; i-- )    {	DELAY(2);			/* 150 cycles for N10 intr roundtrip */	switch (ans = *read_coproc)	/* N10 running at 25-30ns clock */	{	 case 0xdeadbabe:	 case 0x00000000:	    GX_DEBUG(GX_SILENT, gq_intrPending = 0;);	    return -1;	 case GQ_INTR_BUF0:		/* 1 */	    GX_DEBUG(GX_SILENT, gq_intrPending = 0;);	    return 0;	 case GQ_INTR_BUF1:		/* 2 */	    GX_DEBUG(GX_SILENT, gq_intrPending = 0;);	    return 1;	 default:	    if (ans != cmd) {		GX_DEBUG(GX_CONSOLE,			 gx_printf("gq_intr_coproc: 0x%x bad repl=0x%x\n",				   cmd, ans);			 );		rval = 2;		/* > 1 */		goto BadReply;	    }	}    }    GX_DEBUG(GX_CONSOLE,	     gx_printf("gq_intr_coproc: 0x%x dead=0x%x spl %d hst 0x%x\n",		       cmd, ans, whatspl(), GQ_RAM(gqo)->intr_host);	     ); BadReply:    if (gq_debug & GQ_KILL_N10) {	if (GX_HAVESERVER)#	    ifdef p_dev_VM_maint	    gx_serverp->p_dev_VM_maint = 0;#	    endif	    psignal(gx_serverp,SIGILL); /* kill the server */	*GQ_RESET(gqo) = 0;		/* kill the N10 */	wbflush();    }    else    {# 	ifdef p_dev_VM_maint	if (GX_HAVESERVER)	    gx_serverp->p_dev_VM_maint = 0;#	endif    }    GX_DEBUG(GX_SILENT, gq_intrPending = 0;);    gq_N1OK = 0;    return rval;}/* end gq_intr_coproc. */gq_vm_hook(cmd, vpn)			/* alias p_dev_VM_maint */    int cmd, vpn;{    int vsn;    if (GX_HAVESERVER)    {	int reply;	vpn = (int)ptob(vpn) & GQ_INTR_MASK; /* now va, page aligned */	GX_DEBUG(GX_SILENT, gq_invalALL++;);	switch (cmd)	{	 case PDEVCMD_ONE:	    GX_DEBUG(GX_NEVER,		     gx_printf("gq_vm_hook(cmd=1,vpn=0x%x)\n", vpn);		     );	    reply = gq_intr_coproc(vpn | GQ_INTR_INV1);	    GX_DEBUG(GX_CONSOLE,		     char *msg;		     int *pTLB;		     switch (reply) {		      case 2: msg = "REP"; break;		      case 3: msg = "STO"; break;		      case 4: msg = "LTO"; break;		      default:msg = "OK";		     }		     pTLB = (int *)((int)GQ_RAM(gqo) + N10_VTLB_OFF);		     if (pTLB[GQ_VTLB_INDEX(vpn)] == 0 ||			 (pTLB[GQ_VTLB_INDEX(vpn)] & 0xfffff) == 0xbabed) {			 gq_invalOK++;		     } else {			 gx_printf("gq_vm_hook: 0x%x[0x%x] -> 0x%x %s 0x%x\n",				   vpn, GQ_VTLB_INDEX(vpn),				   pTLB[GQ_VTLB_INDEX(vpn)],				   msg, GQ_RAM(gqo)->intr_coproc);		     }		     );	    break;	 case PDEVCMD_ALL:	    GX_DEBUG(GX_NEVER,		     gx_printf("gq_vm_hook(cmd=a,vpn=0x%x)\n", vpn);		     );	    bzero(gq_ptpt, GQ_PTPT_SIZE);	    if (gq_intr_coproc(GQ_INTR_INVA) >= 0)		printf("gq_vm_hook: INVA\n");	    break;	 case PDEVCMD_TOP:	    vsn = vtovsn(vpn);	    GX_DEBUG(GX_NEVER,		     gx_printf("gq_vm_hook(cmd=t,vpn=0x%x:vsn=0x%x)\n",			       vpn, vsn);		     );	    /* I'm assuming that we dont get called here (brk(2) with *	     * change < 0) except when a page table page is freed.    */	    bzero(gq_ptpt + vsn, GQ_PTPT_SIZE - vsn);	    if (gq_intr_coproc(vpn | GQ_INTR_CEIL) >= 0)		printf("gq_vm_hook: CEIL\n");	    break;	 default:	    GX_DEBUG(GX_GAB,		     gx_printf("gq_vm_hook(cmd=bad 0x%x)\n", cmd);		     );	    printf("gq_vm_hook: bad cmd 0x%x\n", cmd);	    panic("gq_vm_hook");	}    }    else	printf("gq_vm_hook: no server?\n");    return 0;}/* end gq_vm_hook. */voidgq_cpu_idleSample(arg)    char *arg;{    if (gq_N1OK) {	register struct cpudata *pcpu=CURRENT_CPUDATA;	gx_info.host_idle = pcpu->cpu_cptime[CP_IDLE];	gx_info.host_idleCount++;	timeout(gq_cpu_idleSample, (char *)0, GQ_CPU_IDLESAMPLE);    }}/* end gq_cpu_idleSample. */gq_close(dev, flag){#   ifdef p_dev_VM_maint    /* unexpress interest in server's vm activity... */    if (GX_HAVESERVER)    {	gx_serverp->p_dev_VM_maint = 0;	*GQ_RESET(gqo) = gq_N1OK = 0;	/* halt N10 */	wbflush();	GX_DEBUG(GX_GAB,		 gx_printf("gq_close: pid=%d\n", gx_serverp->p_pid);		 );    }#   endif    return 0;}/* end gq_close. */gq_config(qp, module_type)    register gxInfo *qp;    int module_type;{    qp->gxo = (char *)gqo;    qp->gram = (int *)GQ_RAM(gqo);    if (module_type == STIC_OPT_2DA) {	printf("gq_config: not 3DA, STIC modtype = %d\n", module_type);	panic("gq_config");    }    return 0;}/* end gq_config. */gq_getPixBuff(p_sva, p_stic)    int **p_sva;			/* sys virt addr */    int *p_stic;			/* stic phys addr */{    u_long sram_addr;    *p_sva = GQ_RAM(gqo)->pixbuf;	/* K1 addr */    sram_addr = GQ_SYS_TO_PHYS(*p_sva);    *p_stic = GX_SYS_TO_STIC(sram_addr);}int *gq_getPacket(){    static int whichBuffer = 0;		/* 0 || 1 */    register int *buf;    /*     * don't collide with N10 over SRAM when xcons not enabled!     * should not be the common case.     */    if (gq_N1OK) {	register int i;			/* ask N10 which packet buffer */					/* we may use. */	whichBuffer = gq_intr_coproc(GQ_INTR_PAUS);	if (whichBuffer < 0 || whichBuffer > 1) {	    GX_DEBUG(GX_TERSE,		     gx_printf("gq_getPacket: bad reply from i860 %d\n",			       whichBuffer);		     );	    return ((int *)(whichBuffer = 0));	}	GX_DEBUG(GX_GAB,		 gx_printf("gq_getPacket: i860->%d\n", whichBuffer);		 );	_POLL_STIC_PINT(i);		/* then wait for stic to be idle */    }					/* since this buffer may be currently */					/* executing */    buf = GQ_REQBUF(gqo, whichBuffer);    whichBuffer ^= 0x1;    return (buf);}/* end gq_getPacket. */gq_sendPacket(buf)    char *buf;				/* virtual addr */{    int i, addr;    volatile int *poll;    /* ... to sram phys addr ... */    addr = GQ_SYS_TO_PHYS(buf);    poll = (int *)((char *)GQ_POLL(gqo) + GX_SYS_TO_DMA(addr));    _POLL_STIC_PINT(i);    _gx_stic->ipdvint = STIC_INT_P_WE;	/* clear pkt done intr bit */    wbflush();				/* make sure all writes completed */    if (*poll != STAMP_GOOD)    {	gx_init_stic();	gx_unwedge_stic++;	if (*poll != STAMP_GOOD) {	    gx_dropped_packet++;	    GX_DEBUG(GX_TERSE,		     gx_printf("STIC:CSR 0x%x B:SR 0x%x A 0x%x D 0x%x I 0x%x\n",			       _gx_stic->sticsr, _gx_stic->buscsr,			       _gx_stic->busadr, _gx_stic->busdat,			       _gx_stic->ipdvint);		     );	    return -1;	}    }					/* if N10 running, then must have */    if (gq_N1OK) {			/* asked permission to do console */	register int k;			/* output, so N10 must be waiting */	_POLL_STIC_PINT(k);		/* for OK to proceed... */	GQ_RAM(gqo)->intr_coproc = 0;	wbflush();    }    return (i);}/* end gq_sendPacket. *//* * THE BEGINNING. */gq_cons_init(){    register int reg;    int tmp1;    extern int cpu, console_magic;    if (cpu == DS_3100) return (0);    reg = tc_where_option("gq");    if (reg == 0)        return (0);    reg = PHYS_TO_K1(reg);    /*     * 3max console ROM changes for enhanced TURBOchannel support     * have eliminated the ability to have multiple outputs.  If     * new ROM is in place, use the output device specifiec by ROM.     */    if (console_magic != 0x30464354) {      tmp1 = atoi(prom_getenv("osconsole"));      if (tmp1 & 0x1) gx_console |= GRAPHIC_DEV;      if (tmp1 & 0x8) gx_console |= CONS_DEV;    }    else {      tmp1 = rex_getenv("osconsole");      if (strlen(tmp1) > 1) {	if (tmp1 & 0x1) gx_console = GRAPHIC_DEV;      }      else {	if (tmp1 & 0x8) gx_console = CONS_DEV;      }    }    GX_DEBUG(GX_GAB,	     gx_printf("gq_cons_init: reg=0x%x\n", reg);	     );    gqo = (gqMap *)reg;			/* K1 physaddr: base of option board */    /*     * KM_ALLOC storage area for gxPriv struct.  This has to be done     * here, since the console code assumes gx_priv exists already!     */    KM_ALLOC(gx_priv, gxPriv *, GQ_PRIV_SIZE, KM_DEVBUF, KM_CLEAR|KM_CONTIG);    if (!gx_priv) return 0;    gx_priv = (gxPriv *)PHYS_TO_K0(svtophy(gx_priv));    /*     * ditto for the ((page table page) table) ...     */    KM_ALLOC(gq_ptpt, int *, GQ_PTPT_SIZE, KM_DEVBUF, KM_CLEAR|KM_CONTIG);    if (!gq_ptpt) return 0;    gq_ptpt = (int *)PHYS_TO_K1(svtophy(gq_ptpt));    gxp = &(gx_info);    gx_rboffset = sizeof(gxPriv)/sizeof(int);    /*     * Required linkage...     */    _gx_vdac       = GQ_VDAC(gqo);    _gx_vdacReset  = GQ_VDACRESET(gqo);    _gx_stamp	   = GQ_STAMP(gqo);	/* stic stamp space    @ 0x..0c0000 */    _gx_stic       = GQ_STIC(gqo);	/* stic register space @ 0x..180000 */    _gx_modtype	   = ((_gx_stic->modcl & ~STIC_CF_CONFIG_OPTION)		      | STIC_OPT_3DA_SH);    _gx_config     = gq_config;    _gx_ioctl	   = gq_ioctl;    _gx_getPacket  = gq_getPacket;    _gx_sendPacket = gq_sendPacket;    _gx_getPixBuff = gq_getPixBuff;    /*     * Optional linkage...     */    _gx_init       = gq_init;    _gx_close	   = gq_close;    gq_init_cons();    return (1);}/* end gq_cons_init. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -