📄 i81xgart.c
字号:
} /* check if we have enough entries for requested reservation */ if (fourKBlocks >= i81xGartInitPtr->num_entries) {#ifdef I81xGART_DEBUG_LVL2 printf ("error: i81xGartReserveCont: input exceeds limit\n");#endif return (NULL); } xPtr = (char *) memalign (4096, 4096 * fourKBlocks); if (xPtr == NULL) {#ifdef I81xGART_DEBUG_LVL2 printf ("error: i81xGartReserveCont: memalign failed.\n");#endif return (NULL); } tmpPtr = xPtr; for (i = 0; i < fourKBlocks; i++, tmpPtr += 4096) {#ifdef I81xGART_DEBUG_LVL2 printf ("status: i81xGartReserveCont: i81xGartInsertPage (0x%X)\n", (int) tmpPtr);#endif i81xGartInsertPage ((void *) tmpPtr); } return (xPtr); }/********************************************************************************* i81xGartPhyToLinear -** RETURNS: OK, if successful else ERROR*/int i81xGartPhyToLinear ( unsigned long phy ) { int i; unsigned long tmp_value = 0; for (i = 0; i < i81xGartInitPtr->num_entries; i++) { tmp_value = i81xGartTablePtr[i]; tmp_value &= 0xFFFFF000; if (tmp_value == phy) break; } return ((unsigned int) (i81xGartGMPhysAddr + (i * 4096))); }/********************************************************************************* i81xInitCmd -** RETURNS: OK, if successful else ERROR*/LOCAL STATUS i81xInitCmd ( ULONG size, ULONG *cmdLinear ) { if (size < 1) return (ERROR); size--; /* Ring Buffer Empty */ I81xGART_MEMMAP_OUT(I81xGART_LPRB_HEADPT, 0); I81xGART_MEMMAP_OUT(I81xGART_LPRB_TAILPT, 0);#ifdef I81xCMD_DEBUG printf ("status: i81xInitCmd: HEAD 0x%X TAIL 0x%X\n", I81xGART_MEMMAP_IN(I81xGART_LPRB_HEADPT), I81xGART_MEMMAP_IN(I81xGART_LPRB_TAILPT));#endif /* Enable the low priority ring buffer Buffer Length : size * 4KB */ I81xGART_MEMMAP_OUT(I81xGART_LPRB_BUFLEN, (size << 12));#ifdef I81xCMD_DEBUG printf ("status: i81xInitCmd: I81xGART_LPRB_BUFLEN 0x%X\n", (int) I81xGART_MEMMAP_IN(I81xGART_LPRB_BUFLEN));#endif /* Phy address of 4KB aligned buffer */ I81xGART_MEMMAP_OUT(I81xGART_LPRB_STADDR, (((ULONG)cmdLinear & 0xFFFFF000) - i81xGartGMPhysAddr));#ifdef I81xCMD_DEBUG printf ("status: i81xInitCmd: I81xGART_LPRB_STADDR 0x%X cmdLinear 0x%X\n", (int) I81xGART_MEMMAP_IN(I81xGART_LPRB_STADDR), (int) cmdLinear);#endif i81xGartCmdLinearAddr = cmdLinear; i81xGartCmdLinearAddrStore = cmdLinear; i81xGartCmdCounter = 0; return (OK); }/********************************************************************************* i81xAddCmd -** RETURNS: OK, if successful else ERROR*/STATUS i81xAddCmd ( ULONG cmd ) { *i81xGartCmdLinearAddr++ = cmd; i81xGartCmdCounter += 4; return (OK); }/********************************************************************************* i81xAddFloatCmd -** RETURNS: OK, if successful else ERROR*/STATUS i81xAddFloatCmd ( float value ) { *((float *) i81xGartCmdLinearAddr) = value; i81xGartCmdLinearAddr++; i81xGartCmdCounter += 4; return (OK); }/********************************************************************************* i81xExecCmd -** RETURNS: OK, if successful else ERROR*/STATUS i81xExecCmd ( void ) { /* Last command must be on an even quad word boundary */ if (i81xGartCmdCounter % 8) i81xAddCmd(0); /* enable LPRB */ I81xGART_MEMMAP_OUT(I81xGART_LPRB_BUFLEN, (I81xGART_MEMMAP_IN(I81xGART_LPRB_BUFLEN) | 0x1));#ifdef I81xCMD_DEBUG printf ("status: i81xExecCmd: I81xGART_LPRB_BUFLEN 0x%X - VALID\n", (int) I81xGART_MEMMAP_IN(I81xGART_LPRB_BUFLEN));#endif /* set tailptr */ I81xGART_MEMMAP_OUT(I81xGART_LPRB_TAILPT, i81xGartCmdCounter);#ifdef I81xCMD_DEBUG printf ("status: i81xExecCmd: i81xGartCmdCounter %d, I81xGART_LPRB_TAILPT 0x%X\n", i81xGartCmdCounter, (int) I81xGART_MEMMAP_IN(I81xGART_LPRB_TAILPT));#endif /* is LPRINGBUF empty? */ while (I81xGART_MEMMAP_IN(I81xGART_LPRB_HEADPT) != I81xGART_MEMMAP_IN(I81xGART_LPRB_TAILPT)); /* disable LPRB */ I81xGART_MEMMAP_OUT(I81xGART_LPRB_BUFLEN, (I81xGART_MEMMAP_IN(I81xGART_LPRB_BUFLEN) & ~0x1));#ifdef I81xCMD_DEBUG printf ("status: i81xExecCmd: I81xGART_LPRB_BUFLEN 0x%X - INVALID\n", (int) I81xGART_MEMMAP_IN(I81xGART_LPRB_BUFLEN));#endif /* reset everything */ I81xGART_MEMMAP_OUT(I81xGART_LPRB_HEADPT, 0); I81xGART_MEMMAP_OUT(I81xGART_LPRB_TAILPT, 0); i81xGartCmdLinearAddr = i81xGartCmdLinearAddrStore; i81xGartCmdCounter = 0; return (OK); }/********************************************************************************* i81xGartInitialize -** RETURNS: OK, if successful else ERROR*/STATUS i81xGartInitialize ( i81x_DRIVER * pI81xDriver ) { int retval; int fourKBlocks = (I81xGART_GFX_APERTURE_SIZE * 0x100); /* Check if the current chipset is supported or not */ if (i81xGartFindSupported() != OK) {#ifdef I81xGART_DEBUG printf("error: i81xGartInitialize: i81xGartFindSupported\n");#endif return (ERROR); } i81xGartMapMem(); retval = i81xGartChipset.initialize(); if (retval != OK) {#ifdef I81xGART_DEBUG printf("error: i81xGartInitialize: i81xGartChipset.initialize FAILED.\n");#endif return (retval); } retval = i81xGartChipset.configure (); if (retval != OK) {#ifdef I81xGART_DEBUG printf("error: i81xGartInitialize: i81xGartChipset.configure FAILED.\n");#endif return (retval); } if (i81xGartChipset.cache_flush_req) FLUSH_CACHE(); i81xGartChipset.tlb_flush(); /* Reserve atleast 4MB of contiguous memory space for IP and 2D engine */ i81xGartAperturePhyBase = (ULONG *) i81xGartReserveCont (fourKBlocks); /* Command data starts from i81xGartAperturePhyBase + 1MB */ i81xGartCmdDataPhyBase = i81xGartAperturePhyBase + 0x40000; /* Source data starts from i81xGartCmdDataPhyBase + 64 KB */ i81xGartSrcDataPhyBase = i81xGartCmdDataPhyBase + 0x4000;#if defined(I81xGART_DEBUG) || defined(I81xCMD_DEBUG) printf("status: Apert 0x%X Src 0x%X Cmd 0x%X \n", (int) i81xGartAperturePhyBase, (int) i81xGartSrcDataPhyBase, (int) i81xGartCmdDataPhyBase);#endif /* reserve 64K for instruction parser */ i81xInitCmd(16, (void *) i81xGartPhyToLinear((ULONG) i81xGartCmdDataPhyBase)); return (OK); }/********************************************************************************* i81xGartGetFBAddr -** RETURNS: OK, if successful else ERROR*/VOID * i81xGartGetFBAddr ( VOID ) { return ((void *) i81xGartPhyToLinear((ULONG)(i81xGartAperturePhyBase))); }#ifdef DEBUG/********************************************************************************* i81xGartAllocPage -** RETURNS: OK, if successful else ERROR*/static void *i81xGartAllocPage ( void ) { void *pt; /* Allocate 4KB aligned memory of size 4KB */ pt = (void *) memalign (4096, 4096); if (pt == NULL) {#ifdef I81xGART_DEBUG_LVL2 printf ("error: i81xGartAllocPage Failed\n");#endif return (NULL); } return (pt); }/********************************************************************************* i81xGartReserve -** RETURNS: OK, if successful else ERROR*/LOCAL STATUS i81xGartReserve ( int fourKBlocks ) { int i; /* validate input */ if (fourKBlocks < 0) {#ifdef I81xGART_DEBUG_LVL2 printf ("error: i81xGartReserve: invalid input %d\n", fourKBlocks);#endif return (ERROR); } /* check if we have enough entries for requested reservation */ if (fourKBlocks >= i81xGartInitPtr->num_entries) {#ifdef I81xGART_DEBUG_LVL2 printf ("error: i81xGartReserve: input exceeds limit\n");#endif return (ERROR); } for (i = 0; i < fourKBlocks; i++) i81xGartInsertPageIdx (i, i81xGartAllocPage()); return (OK); }/********************************************************************************* i81xGartDestoryPage -** RETURNS: OK, if successful else ERROR*/static void i81xGartDestroyPage ( void *pt ) { if (pt == NULL) return; free (pt); }/********************************************************************************* i81xGartFreeTable** RETURNS: OK, if successful else ERROR*/LOCAL void i81xGartFreeTable ( void ) { int i; void *tmp_ptr; unsigned long tmp_value; for(i = 0; i < i81xGartInitPtr->num_entries; i++) { if(i81xGartTablePtr[i] != 0) { tmp_value = i81xGartTablePtr[i]; i81xGartTablePtr[i] = 0; tmp_value &= ~(i81xGartEntrySettings); tmp_ptr = (void *) tmp_value; i81xGartDestroyPage(tmp_ptr); } } free (i81xGartTablePtr); }/********************************************************************************* i81xGartRemovePage -** RETURNS: OK, if successful else ERROR*/static int i81xGartRemovePage ( void * pagePhyAdrs ) { unsigned long tmp_value; int i; for (i = 0; i < i81xGartInitPtr->num_entries; i++) { tmp_value = i81xGartTablePtr[i]; if (!PGE_EMPTY(tmp_value)) { void *tmp_ptr;#ifdef I81xGART_DEBUG_LVL2 printf ("status: i81xGartRemovePage: PGE_EMPTY(0x%X) @ idx %d.\n", (int) tmp_value, i);#endif tmp_value &= ~(i81xGartEntrySettings); tmp_ptr = (void *) (tmp_value); i81xGartDestroyPage(tmp_ptr); i81xGartChipset.write_entry(i, 0); if (i81xGartChipset.cache_flush_req) FLUSH_CACHE(); break; } } return (OK); }/********************************************************************************* i81xGartRemovePageIdx -** RETURNS: OK, if successful else ERROR*/static int i81xGartRemovePageIdx ( int gart_index ) { unsigned long tmp_value; if (gart_index < 0 || gart_index >= i81xGartInitPtr->num_entries) {#ifdef I81xGART_DEBUG_LVL2 printf ("error: i81xGartRemovePageIdx: invalid gart_index %d\n", gart_index);#endif return (ERROR); } /* Check if valid entry exists */ tmp_value = i81xGartTablePtr[gart_index]; if(tmp_value & 0x1) { void *tmp_ptr;#ifdef I81xGART_DEBUG_LVL2 printf ("status: i81xGartRemovePageIdx: Destroying 0x%X at 0x%X\n", (int) tmp_value, gart_index);#endif tmp_value &= ~(i81xGartEntrySettings); tmp_ptr = (void *) (tmp_value); i81xGartDestroyPage(tmp_ptr); i81xGartChipset.write_entry(gart_index, 0); } if (i81xGartChipset.cache_flush_req) FLUSH_CACHE(); return (OK); }void i81xTestExec ( void ) { unsigned int * tmpPtr; tmpPtr = memalign (4096, 4096); /* GFXCMDPARSER_NOP_IDENTIFICATION */ i81xAddCmd ((1 << 22) | 0x001A5A00); /* GFXCMDPARSER_STORE_DWORD_IMM */ i81xAddCmd ((0x20 << 23) | 0x1); i81xAddCmd ((int) tmpPtr); i81xAddCmd (0xDEADDEED); /* execute command */ i81xExecCmd(); printf("status: GFXCMDPARSER_STORE_DWORD_IMM stored 0x%X @ 0x%X\n", (int) *tmpPtr, (int) tmpPtr); free (tmpPtr); }void i81xGartDebug ( void ) { int i; I81xGART_INIT_PARAMS_TYPE * tmp_ptr; int j = (sizeof (i81xGartInitParams) / sizeof (I81xGART_INIT_PARAMS_TYPE)); printf ("i81xGartMMAddr 0x%X, i81xGartGMPhysAddr 0x%X\n", (int) i81xGartMMAddr, (int) i81xGartGMPhysAddr); printf ("i81xGartStartAddr 0x%X, i81xGartTablePtr 0x%X\n", (int) i81xGartStartAddr, (int) i81xGartTablePtr); printf ("PGETBL_CTL 0x%X, i81xGartInitPtr 0x%X\n", (int) I81xGART_MEMMAP_IN(I81xGART_PGETBL_CTL), (int) i81xGartInitPtr); for (i = 0; i < j; i++) { tmp_ptr = &i81xGartInitParams [i]; printf ("i81xGartInitParams[%d] 0x%X: sz %d ord %d ent %d dcache %d\n", i, (int) tmp_ptr, tmp_ptr->size, tmp_ptr->page_order, tmp_ptr->num_entries, tmp_ptr->num_dcache_entries); } printf ("i81xGartChipset : type 0x%X, cache %d\n", i81xGartChipset.type, i81xGartChipset.cache_flush_req); printf ("i81xGartChipset : hh.bus %d, hh.dev %d, hh.fn %d\n", i81xGartChipset.hosthub.bus, i81xGartChipset.hosthub.dev, i81xGartChipset.hosthub.fn); printf ("i81xGartChipset : gfx.bus %d, gfx.dev %d, gfx.fn %d\n", i81xGartChipset.gfx.bus, i81xGartChipset.gfx.dev, i81xGartChipset.gfx.fn); } void i81xGartTest ( int pages ) { int i; if (pages <= 0) return; printf ("status i81xGartTest: adding %d Pages\n", pages); for (i = 0; i < pages; i++) { i81xGartInsertPageIdx (i, i81xGartAllocPage()); } printf ("status i81xGartTest: added %d Pages\n", pages); printf ("status i81xGartTest: removing %d Pages\n", pages); for (i = 0; i < pages; i++) { i81xGartRemovePageIdx (i); } printf ("status i81xGartTest: removed %d Pages\n", pages); printf ("status i81xGartTest: test completed.\n"); }#endif /* DEBUG *//******************************************************************************* i81xGartDeinitialize() - free the memory allocated for the GART** NOMANUAL*/void i81xGartDeinitialize() { free(i81xGartAperturePhyBase); free (i81xGartTablePtr); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -