gart.c
来自「用于查询PC机上的USB端口是否有设备挂接上」· C语言 代码 · 共 395 行
C
395 行
/****************************************************************************
* *
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY *
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR *
* PURPOSE. *
* *
* Copyright (C) 1993-95 Microsoft Corporation. All Rights Reserved. *
* *
****************************************************************************/
/*
* GART.C - XYZ chipset's GART miniport routines.
*
* Notes:
*
*/
#include "pch.h"
#define APSIZE 0
#define APBASE 0
typedef struct _GARTINSTANCEDATA GARTINSTANCEDATA, *PGARTINSTANCEDATA;
//
// GART instance data.
//
struct _GARTINSTANCEDATA {
ULONG ulInstance; // Must be first
ULONG ulGARTRegionBase;
ULONG ulGARTRegionSize;
ULONG ulReserveValue;
ULONG ulFreeValue;
PULONG pulLinearGARTTableBase;
ULONG ulGARTTableEntryCount;
};
VOID
FillMemory(PULONG pWhere, ULONG ulCount, ULONG ulValue)
{
for (;ulCount; ulCount--, pWhere++)
*pWhere=ulValue;
}
/*******************************************************************************
*
* PCIMP_GARTInit - Initializes the GART miniport
*
* Exported.
*
* ENTRY: ulInstance is the miniport instance.
*
* pHandle is the handle on the GART PCI device.
*
* ppRefData returns the miniport's ref data.
*
* EXIT: PCIMP_SUCCESS if successful, PCIMP_FAILURE otherwise.
*
*******************************************************************************/
PCIMPRET CDECL
PCIMP_GARTInit(ULONG ulInstance, PVOID pHandle, PVOID *ppRefData)
{
ULONG ulGARTSize, ulGARTBase;
PGARTINSTANCEDATA pGARTInstance;
UCHAR bBusGART, bDevFuncGART;
//
// Get our info.
//
PCIGetHandleInfo(pHandle, (PULONG)&bBusGART, (PULONG)&bDevFuncGART);
//
// Get the current GART max size.
//
ulGARTSize=ReadConfigUlong(bBusGART, bDevFuncGART, APSIZE);
ulGARTBase=ReadConfigUlong(bBusGART, bDevFuncGART, APBASE) & ~0xF;
if ((pGARTInstance=ExAllocatePool(PagedPool, sizeof(GARTINSTANCEDATA)))==NULL)
return(PCIMP_FAILURE);
pGARTInstance->ulGARTRegionBase=ulGARTBase;
pGARTInstance->ulGARTRegionSize=ulGARTSize;
*ppRefData=pGARTInstance;
return(PCIMP_SUCCESS);
}
/*******************************************************************************
*
* PCIMP_GARTExit - Exits GART miniport
*
* Exported.
*
* ENTRY: pHandle is the handle on the GART PCI device.
*
* pRefData is the miniport's ref data.
*
* EXIT: None.
*
*******************************************************************************/
VOID CDECL
PCIMP_GARTExit(PVOID pHandle, PVOID pRefData)
{
//
// Nothing to do.
//
}
/******************************************************************************
*
* PCIMP_GARTReset - Resets the GART
*
* Exported.
*
* ENTRY: pHandle is the handle on the GART PCI device.
*
* pRefData indicates which GART we are using.
*
* ulPhysPageCount is the number of physical pages in the system.
*
* ulInvalidAddr1 is the physical address for free GART entries.
*
* ulInvalidAddr2 is the physical address for reserved GART
* entries.
*
* pulFeatures is the pointer to the variable that will receive
* the GART features.
*
* EXIT: PCIMP_SUCCESS iff successful, PCIMP_FAILURE iff not.
*
******************************************************************************/
PCIMPRET CDECL
PCIMP_GARTReset(PVOID pHandle, PVOID pRefData, ULONG ulPhysPageCount, ULONG ulInvalidAddr1, ULONG ulInvalidAddr2, PULONG pulFeatures)
{
ULONG ulGARTTableSize;
PHYSICAL_ADDRESS pa;
UCHAR bBusGART, bDevFuncGART;
PGARTINSTANCEDATA pGARTInstance=(PGARTINSTANCEDATA)pRefData;
//
// Features will be determined by Microsoft for each chipset. This is for internal use only.
//
*pulFeatures=0;
//
// Set our special values.
//
pGARTInstance->ulReserveValue=ulInvalidAddr1;
pGARTInstance->ulFreeValue=0;
//
// Compute the GART table size.
//
ulGARTTableSize=(pGARTInstance->ulGARTRegionSize/PAGE_SIZE)*sizeof(ULONG);
//
// Round up the GART table size.
//
ulGARTTableSize=(ulGARTTableSize+PAGE_SIZE-1) & (~(PAGE_SIZE-1));
//
// Compute the GART entry count.
//
pGARTInstance->ulGARTTableEntryCount=ulGARTTableSize/sizeof(ULONG);
//
// Allocate the linear address for the GART table.
//
pa.HighPart=MAXULONG;
pa.LowPart=MAXULONG;
if ((pGARTInstance->pulLinearGARTTableBase=PCIAllocatePages(ulGARTTableSize/PAGE_SIZE, 0, PCIPAGECONTIG))==NULL)
return(PCIMP_FAILURE);
//
// Initialize by freeing everything.
//
PCIMP_GARTFree(pHandle, pGARTInstance, pGARTInstance->ulGARTTableEntryCount, pGARTInstance->pulLinearGARTTableBase);
//
// Get our info.
//
PCIGetHandleInfo(pHandle, (PULONG)&bBusGART, (PULONG)&bDevFuncGART);
//
// Do whatever it takes to setup the GART base pointer in the chipset.
//
return(PCIMP_SUCCESS);
}
/******************************************************************************
*
* PCIMP_GARTReserve - Reserves entries in the GART
*
* Exported.
*
* ENTRY: pHandle is the handle on the GART PCI device.
*
* pRefData indicates which GART we are using.
*
* ulNumPages is the number of physical pages for which entries
* need to be allocated in the GART.
*
* ulAlignment is the desired alignment.
*
* ppMapHandle is a pointer to variable that receives the handle
* to be used during Map/UnMap and Flush.
*
* pulGARTDev is a pointer to a variable that receives the base
* physical address in the AGP aperture for GART entries
* allocated.
*
* ulFlags specifies the type of memory for which entries need
* to be allocated.
*
* EXIT: PCIMP_SUCCESS iff successful.
*
******************************************************************************/
PCIMPRET CDECL
PCIMP_GARTReserve(PVOID pHandle, PVOID pRefData, ULONG ulNumPages, ULONG ulAlignMask, PVOID *ppMapHandle, PULONG pulGARTDev, ULONG ulFlags)
{
ULONG ulGARTHandle, i;
BOOLEAN fFound;
PGARTINSTANCEDATA pGARTInstance=(PGARTINSTANCEDATA)pRefData;
//
// Convert alignment into an increment.
//
ulAlignMask++;
//
// Scan the GART.
//
ulGARTHandle=0;
while (ulGARTHandle<pGARTInstance->ulGARTTableEntryCount) {
//
// Check at ulGARTHandle;
//
fFound=TRUE;
for (i=0;i<ulNumPages;i++) {
//
// Is it occupied?
//
if (*(pGARTInstance->pulLinearGARTTableBase+ulGARTHandle+i)!=0) {
//
// Yes, so we did not found a contiguous
// region starting at ulGARTHandle.
//
fFound=FALSE;
break;
}
}
//
//
//
if (fFound) {
*pulGARTDev=pGARTInstance->ulGARTRegionBase+(ulGARTHandle*PAGE_SIZE);
*ppMapHandle=(PVOID)(pGARTInstance->pulLinearGARTTableBase+ulGARTHandle);
PCIMP_GARTUnMap(pHandle, pGARTInstance, ulNumPages, *ppMapHandle, 0);
return(PCIMP_SUCCESS);
}
//
// We failed at i, so the best next entry is at i+1. To
// normalize, we need to add ulAlignMask-1 and truncate.
//
ulGARTHandle+=(i+ulAlignMask);
ulGARTHandle&=(~(ulAlignMask-1));
}
//
// We are full. Sorry.
//
return(PCIMP_FAILURE);
}
/******************************************************************************
*
* PCIMP_GARTMap - Map entries in the GART
*
* Exported.
*
* ENTRY: pHandle is the handle on the GART PCI device.
*
* pRefData indicates which GART we are using.
*
* ulNumPages is the number of pages for which entries need to
* be map in the GART.
*
* pMapHandle is the reserve ref data.
*
* ulByteOffset is the offset from the original reserve call.
*
* pSystemLin is the linear address of the system pages to map
* in.
*
* EXIT: None.
*
******************************************************************************/
VOID CDECL
PCIMP_GARTMap(PVOID pHandle, PVOID pRefData, ULONG ulNumPages, PULONG pMapHandle, ULONG ulByteOffset, PUCHAR pSystemLin)
{
pMapHandle+=(ulByteOffset>>PAGE_SHIFT);
for (;ulNumPages; ulNumPages--, pMapHandle++, pSystemLin+=PAGE_SIZE)
*pMapHandle=PCILinToPhys((PVOID)(ULONG)pSystemLin);
}
/******************************************************************************
*
* PCIMP_GARTFlush - Flush entries in the GART
*
* Exported.
*
* ENTRY: pHandle is the handle on the GART PCI device.
*
* pRefData indicates which GART we are using.
*
* ulNumPages is the number of pages for which entries need to
* be flushed in the GART.
*
* pMapHandle is the reserve ref data.
*
* ulByteOffset is the offset from the original reserve call.
*
* pSystemLin is the linear address of the system pages to flush.
*
* EXIT: None.
*
******************************************************************************/
VOID CDECL
PCIMP_GARTFlush(PVOID pHandle, PVOID pRefData, ULONG ulNumPages, PULONG pMapHandle, ULONG ulByteOffset, PVOID pSystemLin)
{
//
// Flush if the chipset can.
//
}
/******************************************************************************
*
* PCIMP_GARTUnMap - Unmap entries in the GART
*
* Exported.
*
* ENTRY: pHandle is the handle on the GART PCI device.
*
* pRefData indicates which GART we are using.
*
* ulNumPages is the number of pages for which entries need to
* be unmap in the GART.
*
* pMapHandle is the reserve ref data.
*
* ulByteOffset is the offset from the original reserve call.
*
* EXIT: None.
*
******************************************************************************/
VOID CDECL
PCIMP_GARTUnMap(PVOID pHandle, PVOID pRefData, ULONG ulNumPages, PULONG pMapHandle, ULONG ulByteOffset)
{
FillMemory(pMapHandle+(ulByteOffset>>PAGE_SHIFT), ulNumPages, ((PGARTINSTANCEDATA)pRefData)->ulReserveValue);
}
/******************************************************************************
*
* PCIMP_GARTFree - Free entries in the GART
*
* Exported.
*
* ENTRY: pHandle is the handle on the GART PCI device.
*
* pRefData indicates which GART we are using.
*
* ulNumPages is the number of pages for which entries need to
* be unmap in the GART.
*
* pMapHandle is the reserve ref data.
*
* EXIT: None.
*
******************************************************************************/
VOID CDECL
PCIMP_GARTFree(PVOID pHandle, PVOID pRefData, ULONG ulNumPages, PULONG pMapHandle)
{
FillMemory(pMapHandle, ulNumPages, ((PGARTINSTANCEDATA)pRefData)->ulFreeValue);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?