📄 ga.c
字号:
/****************************************************************** ** gaintr() ** ** Interrupt from STIC ** ** ** ******************************************************************/#ifdef notdef#define SUBMIT_PACKET(i) \ while (*pCom2d->intr_qpoll[i] == STAMP_BUSY) {}#else#define SUBMIT_PACKET(i) \ status = *pCom2d->intr_qpoll[i]#endif notdefgaintr(unit) register int unit;{ GX_DEBUG(GX_NEVER, gx_puts("gaintr()\n"); ); if (_gx_stic->ipdvint & STIC_INT_P) { /* Packet Int */ register Com2dPtr pCom2d = (Com2dPtr) &gaComArea->SRV2DCom; register int cp; register ga_PacketPtr pPkt; register int status;#ifdef notdef gaPintr_count[unit]++;#endif notdef /* clear *only* packet done interrupt */ _gx_stic->ipdvint = (_gx_stic->ipdvint | STIC_INT_P_WE) & ~(STIC_INT_E_WE | STIC_INT_V_WE | STIC_INT_P); /* if were idle, dismiss this as a spurious interrupt */ if (pCom2d->lastRead == pCom2d->lastWritten || !(pCom2d->intr_status & GA_INTR_ACTIVE)) return 1; /* * If we are in the process of sending a packet through a cliplist, * fixup packet with next cliprect and resubmit. If the last * cliprect just completed, clear the clipping status. */ if (pCom2d->intr_status & GA_INTR_CLIP) { if (pCom2d->numCliprect-- > 0) { *pCom2d->fixCliprect = *pCom2d->pCliprect++; SUBMIT_PACKET(pCom2d->lastRead); return 1; } else { pCom2d->intr_status &= ~GA_INTR_CLIP; } }loop: /* point past packet just completed */ cp = pCom2d->lastRead = NEXT_BUF(pCom2d, pCom2d->lastRead); /* if no more packets to process, set idle status */ if (cp == pCom2d->lastWritten) { pCom2d->intr_status &= ~GA_INTR_ACTIVE; return 1; } pPkt = (ga_PacketPtr) gaComArea->IntrBuf[cp]; if (pPkt->un.un.opcode == N_PASSPACKET) { int clip_idx = (int) (unsigned short) pPkt->un.PassPacket.cliplist_sync; if (clip_idx != N_NO_CLIPLIST) { int nrects = gaComArea->ClipL[clip_idx].numClipRects; int fix_off = DECODE_CLIP_INDEX(pPkt->un.PassPacket.data); gaStampClipRect *pFixup = (gaStampClipRect *) &pPkt->un.PassPacket.data[fix_off]; *pFixup = gaComArea->ClipL[clip_idx].clipRects[0]; if (nrects > 1) { pCom2d->pCliprect = &gaComArea->ClipL[clip_idx].clipRects[1]; pCom2d->numCliprect = nrects-1; pCom2d->fixCliprect = pFixup; pCom2d->intr_status |= GA_INTR_CLIP; } } SUBMIT_PACKET(cp); return 1; } else { /* not a pass packet, skip it */ goto loop; } /* end if */ } else if (_gx_stic->ipdvint & STIC_INT_V) { /* Vert Int */ gaVintr_count[unit]++; _gx_stic->ipdvint = (_gx_stic->ipdvint | STIC_INT_V_WE) & ~(STIC_INT_E_WE | STIC_INT_P_WE | STIC_INT_V); } else if (_gx_stic->ipdvint & STIC_INT_E) { /* Error Int */ gaEintr_count[unit]++; gx_init_stic(); cprintf("STIC intr 0x%x CSR 0x%x B:CSR 0x%x addr 0x%x dat 0x%x\n", _gx_stic->ipdvint, _gx_stic->sticsr, _gx_stic->buscsr, _gx_stic->busadr, _gx_stic->busdat); } else { /* stray ??? */ gaSintr_count[unit]++; }} /* end gaintr() */ga_config(qp, module_type) register gxInfo *qp; int module_type;{ qp->gxo = (char *)gao; qp->stic_dma_rb = GA_POLL(gao); if (module_type != STIC_OPT_2DA) cprintf("ga_config: not 2DA, STIC modtype = %d\n", module_type);} /* end ga_config() *//****************************** * ga_getPacket(): * We need to fix this so the console doesn't step on top of data * structures used by the server. ??? XXX ******************************/int*ga_getPacket(){ static u_int i = 1; register int *buf; /* use nK buffers for now */ buf = gx_ringbuffer + ((GA_CONSIZ >> 2) * i) + 3; i ^= 1; /* toggle between buffers */ return (buf);} /* end ga_getPacket() *//****************************** * ga_sendPacket(): ******************************/intga_sendPacket(buf) /* -> # polls; 0 == timeout */ char *buf; /* virtual addr */{ register u_long i; volatile u_long *poll; register int save_ipdvint; poll = (u_long *)((char *)GA_POLL(gao) + GX_SYS_TO_DMA((int)buf)); /* disable packet-done interrupts */ _gx_stic->ipdvint = ((save_ipdvint =_gx_stic->ipdvint) | STIC_INT_P_WE) & ~(STIC_INT_E_WE | STIC_INT_V_WE | STIC_INT_P_EN); wbflush(); /* make sure all writes completed */ /* * wait for stic to be ready to accept next packet. note that we never * wait forever. we'll time out and go ahead and see if the stic will * accept a packet anyway. if not, _then_ we complain... */ for (i = 0; i < STAMP_RETRIES; i++) { if (_gx_stic->ipdvint & STIC_INT_P) break; DELAY(STAMP_DELAY); } /* * Restore ipdvint state, clearing the STIC_INT_P bit. If interrupts * were enabled before, they will be re-enabled. gaintr() is capable * of dealing with spurious interrupts generated while the server is * running. */ _gx_stic->ipdvint = (save_ipdvint | STIC_INT_P_WE) & ~(STIC_INT_E_WE | STIC_INT_V_WE | STIC_INT_P); wbflush(); if (*poll != STAMP_GOOD) { printf("STIC dead?!\n "); printf("CSR 0x%x Bus CSR 0x%x addr 0x%x dat 0x%x int 0x%x\n", _gx_stic->sticsr, _gx_stic->buscsr, _gx_stic->busadr, _gx_stic->busdat, _gx_stic->ipdvint); _gx_stic->ipdvint = save_ipdvint | STIC_INT_WE; wbflush(); return(-1); } return (i);} /* end ga_sendPacket() */#if 0#define GA_INTR_MASK 0xfffff000int ga_vm_cnt[3] = { 0 };ga_vm_hook(cmd, vpn) /* alias p_dev_VM_maint */ int cmd, vpn;{ if (GX_HAVESERVER) { int va = (int)ptob(vpn) & GA_INTR_MASK; /* now va, page aligned */ switch (cmd) { case PDEVCMD_ONE: GX_DEBUG(GX_GAB, gx_printf("ga_vm_hook(cmd=1,va=0x%x)\n", cmd, va); ); (ga_vm_cnt[0])++; break; case PDEVCMD_ALL: GX_DEBUG(GX_GAB, gx_printf("ga_vm_hook(cmd=a,va=0x%x)\n", cmd, va); ); (ga_vm_cnt[1])++; break; case PDEVCMD_TOP: GX_DEBUG(GX_GAB, gx_printf("ga_vm_hook(cmd=t,va=0x%x)\n", cmd, va); ); (ga_vm_cnt[2])++; break; default: GX_DEBUG(GX_GAB, gx_printf("ga_vm_hook(cmd=? 0x%x)\n", cmd); ); cprintf("ga_vm_hook: bad cmd 0x%x\n", cmd); panic("ga_vm_hook"); } } else printf("ga_vm_hook: no server?\n"); return 0;}/* end ga_vm_hook. */ga_open(dev, flag){# ifdef p_dev_VM_maint /* express interest in server's vm activity... */ if (GX_IAMSERVER) { gx_serverp->p_dev_VM_maint = ga_vm_hook; GX_DEBUG(GX_GAB, gx_printf("ga_open: pid=%d\n", gx_serverp->p_pid); ); }# endif}/* end ga_open. */#endif 0/****************************************************************** ** ga_cons_init(): ** ** Graphic device console initialization. This routine gets ** ** called before anything else, and is (among other things) ** ** the only safe place to allocate physically contiguous ** ** memory. ** ** ** ******************************************************************/extern int console_magic;ga_cons_init(){ register int reg; int tmp1,tmp2; /* ROM debug only */ extern int cpu; if (cpu == DS_3100) return (0); reg = tc_where_option("ga"); 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("ga_cons_init(reg=0x%x)\n", reg); ); gao = (gaMap *)reg; /* begin required linkage */ _gx_vdac = GA_VDAC(gao); _gx_vdacReset = GA_ROM(gao); /* write-only */ _gx_stamp = reg + 0xc0000; /* stic stamp space @ 0x..0c0000 */ _gx_stic = GA_STIC(gao); /* stic register space @ 0x..180000 */ _gx_modtype = ((_gx_stic->modcl & ~STIC_CF_CONFIG_OPTION) | STIC_OPT_2DA_SH); _gx_config = ga_config; _gx_ioctl = ga_ioctl; _gx_getPacket = ga_getPacket; _gx_sendPacket = ga_sendPacket; /* begin optional linkage */# if 0 _gx_open = ga_open;# endif 0 _gx_close = ga_close; /* * The STIC DMA area for the 2D accelerator has unusual * alignment requirements: The physical starting address must be a * 32K-aligned address. * Because all the stamp packets have a 3-longword microcode header, * the the ring buffer must start 12 bytes before that. */ /* * This is number of bytes to km_alloc(). 128Kb + (1 page) extra * are allocated, within which will be located a 32Kb-aligned * STIC packet DMA area. */ gx_priv_size = sizeof(gxPriv) + _128K + NBPG;# ifdef GA_ALLOC_KM KM_ALLOC(gx_priv, gxPriv *, gx_priv_size, KM_DEVBUF, KM_NOW_CL_CO_CA); gx_priv = (gxPriv *) svtophy(gx_priv); if ((u_long)gx_priv >= (0x800000-gx_priv_size)) { printf("ga_cons_init: km_alloc out-of-bounds 0x%x\n", gx_priv); panic("ga_cons_init"); } gx_priv = (gxPriv *) (PHYS_TO_K1(gx_priv));# endif# ifdef GA_ALLOC_DT gx_priv = (gxPriv *) (PHYS_TO_K1(Ring2da));# endif# ifdef GA_ALLOC_TX gx_priv = (gxPriv *) PHYS_TO_K1(ga_dummy);# endif tmp1 = (int)&gx_priv->ringbufferoffset + 4;# define TMPMASK ((1<<15) - 1) gx_priv->ringbufferoffset = ( (tmp1 + TMPMASK & ~TMPMASK) - 12 - (int)gx_priv ) / 4;# undef TMPMASK /* if before the beginning, adjust upwards by 8K *longwords* */ if (gx_priv->ringbufferoffset < 0) gx_priv->ringbufferoffset += (1 << 13); { register int i; gaComArea = (ga_ComAreaPtr) gx_ringbuffer; GX_DEBUG(GX_YAK, gx_printf("ga_cons_init: comarea=0x%x\n", gaComArea); ); for (i = 0; i < GA_QUEUE_PACKETS; i++) { gaComArea->SRV2DCom.intr_qpoll[i] = (long *)((char *)GA_POLL(gao) + GX_SYS_TO_DMA(&gaComArea->IntrBuf[i][3])); GX_DEBUG(GX_YAK, gx_printf("ga_cons_init: Q#%d qpoll=0x%x intrbuf=0x%x\n", i, gaComArea->SRV2DCom.intr_qpoll[i], gaComArea->IntrBuf[i]); ); } } gxp = &(gx_info); GX_DEBUG(GX_GAB, int *pb1; int *pb2; gx_printf("ga_cons_init: priv=0x%x vdac=0x%x, rboff=%d\n", gx_priv, _gx_vdac, gx_priv->ringbufferoffset); pb1 = pb2 = ga_getPacket(); gx_puts("ga_cons_init: buf stic dma poll\n"); do { u_long r1; u_long r2; r1 = GX_SYS_TO_STIC(pb2); r2 = GX_SYS_TO_DMA(pb2); gx_printf(" 0x%8x 0x%8x 0x%8x 0x%8x\n", pb2, r1, r2, (char *)GA_POLL(gao) + r2 ); pb2 = ga_getPacket(); } while (pb1 != pb2); ); ga_init_cons(); return (1);} /* end ga_cons_init() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -