📄 pciautoconfiglib.c
字号:
* This optional user-specified routine takes as input both the* bus-device-function tuple, and a 32-bit quantity containing both* the PCI deviceID and vendorID of the device. The function prototype* for this function is shown below:* .CS* STATUS sysPciAutoconfigPostEnumBridgeInit* (* PCI_SYSTEM *pSys,* PCI_LOC *pLoc,* UINT devVend* );* .CE* This routine may use any combination of these input data to* ascertain any special initialization requirements of a particular* type of bridge at a specified geographic location.** .IP "PCI_ROLLCALL_FUNC_SET - FUNCPTR * pArg"* The specified routine will be configured as a roll call routine.** If a roll call routine has been configured, before any* configuration is actually done, the roll call routine is called* repeatedly until it returns TRUE. A return value of TRUE indicates* that either (1) the specified number and type of devices named in* the roll call list have been found during PCI bus enumeration or* (2) the timeout has expired without finding all of the specified* number and type of devices. In either case, it is assumed that all* of the PCI devices which are going to appear on the busses have* appeared and we can proceed with PCI bus configuration.** .IP "PCI_TEMP_SPACE_SET - char * pArg"* This command is not currently implemented. It allows the user to* set aside memory for use during pciAutoConfigLib execution, e.g.* memory set aside using USER_RESERVED_MEM. After PCI configuration* has been completed, the memory can be added to the system memory* pool using memAddToPool().** .IP "PCI_MINIMIZE_RESOURCES"* This command is not currently implemented. It specifies that* pciAutoConfigLib minimize requirements for memory and I/O space.** .IP "PCI_PSYSTEM_STRUCT_COPY - PCI_SYSTEM * pArg"* This command has been added for ease of converting from the old* interface to the new one. This will set each value as specified in* the pSystem structure. If the PCI_SYSTEM structure has already* been filled, the pciAutoConfig(pSystem) call can be changed* to:* .CS* void *pCookie;* pCookie = pciAutoConfigLibInit(NULL);* pciAutoCfgCtl(pCookie, PCI_PSYSTEM_STRUCT_COPY, (void *)pSystem);* pciAutoCfgFunc(pCookie);* .CE* * The fields of the PCI_SYSTEM structure are defined below. For more* information about each one, see the paragraphs above and the* documentation for pciAutoConfigLib.* * .IP "pciMem32" 16* Specifies the 32-bit prefetchable memory pool base address. * * .IP "pciMem32Size" 16* Specifies the 32-bit prefetchable memory pool size.* * .IP "pciMemIo32" 16* Specifies the 32-bit non-prefetchable memory pool base address.* * .IP "pciMemIo32Size" 16* Specifies the 32-bit non-prefetchable memory pool size* * .IP "pciIo32" 16* Specifies the 32-bit I/O pool base address. * * .IP "pciIo32Size" 16* Specifies the 32-bit I/O pool size. * * .IP "pciIo16" 16* Specifies the 16-bit I/O pool base address. * * .IP "pciIo16Size" 16* Specifies the 16-bit I/O pool size. * * .IP "includeRtn" 16* Specifies the device inclusion routine.* * .IP "intAssignRtn" 16* Specifies the interrupt assignment routine.* * .IP "autoIntRouting" 16* Can be set to TRUE to configure pciAutoConfig() only to* call the BSP interrupt routing routine for devices on bus number 0.* Setting autoIntRoutine to FALSE will configure pciAutoConfig()* to call the BSP interrupt routing routine for every device* regardless of the bos on which the device resides.* * .IP "bridgePreInit" 16* Specifies the bridge initialization routine to call* before initializing devices on the bus that the bridge* implements.* * .IP "bridgePostInit" 16* Specifies the bridge initialization routine to call* after initializing devices on the bus that the bridge* implements.* * ERRNO:* EINVAL if pCookie is not NULL or cmd is not recognized** RETURNS: OK, or ERROR if the command or argument is invalid.**/STATUS pciAutoCfgCtl ( void * pCookie, /* system configuration information */ int cmd, /* command word */ void * pArg /* argument for the cmd */ ) { PCI_SYSTEM * pSystem; PCI_AUTO_CONFIG_OPTS * pOpts; if ( pCookie == NULL ) { errnoSet(EINVAL); return(ERROR); } pOpts = (PCI_AUTO_CONFIG_OPTS *)pCookie; switch (cmd) { case PCI_PSYSTEM_STRUCT_COPY: /* copy from pSystem to pOpt */ if ( pArg == NULL ) { errnoSet(EINVAL); return(ERROR); } pSystem = (PCI_SYSTEM *)pArg; pOpts->pciMem32 = pSystem->pciMem32; pOpts->pciMem32Size = pSystem->pciMem32Size; pOpts->pciMemIo32 = pSystem->pciMemIo32; pOpts->pciMemIo32Size = pSystem->pciMemIo32Size; pOpts->pciIo32 = pSystem->pciIo32; pOpts->pciIo32Size = pSystem->pciIo32Size; pOpts->pciIo16 = pSystem->pciIo16; pOpts->pciIo16Size = pSystem->pciIo16Size; pOpts->maxBus = pSystem->maxBus; pOpts->cacheSize = pSystem->cacheSize; pOpts->maxLatency = pSystem->maxLatency; pOpts->autoIntRouting = pSystem->autoIntRouting; pOpts->includeRtn = pSystem->includeRtn; pOpts->intAssignRtn = (PCI_INT_ASSIGN_FUNC)pSystem->intAssignRtn; pOpts->bridgePreConfigInit = pSystem->bridgePreConfigInit; pOpts->bridgePostConfigInit = pSystem->bridgePostConfigInit; pOpts->pciRollcallRtn = pSystem->pciRollcallRtn; break; case PCI_MINIMIZE_RESOURCES: pOpts->minimizeResources = (BOOL)pArg; break; case PCI_FBB_ENABLE: pOpts->pciFBBEnable = TRUE; pOpts->pciFBBActive = FALSE; if ( pciAutoConfigFBBEnable(pOpts) == OK ) { pOpts->pciFBBActive = TRUE; } if ( pArg != NULL ) { (*(BOOL *)pArg) = pOpts->pciFBBActive; } break; case PCI_FBB_DISABLE: if ( ( pOpts->pciFBBEnable == TRUE ) || ( pOpts->pciFBBActive == TRUE ) ) { pciAutoConfigFBBDisable(pOpts); pOpts->pciFBBActive = FALSE; } pOpts->pciFBBEnable = FALSE; break; case PCI_FBB_UPDATE: if ( ( pOpts->pciConfigInit == TRUE ) && ( pOpts->pciFBBEnable == TRUE ) ) { pOpts->pciFBBActive = pciAutoConfigFBBEnable(pOpts); } if ( pArg != NULL ) { (*(BOOL *)pArg) = pOpts->pciFBBActive; } break; case PCI_FBB_STATUS_GET: (*(BOOL *)pArg) = pOpts->pciFBBEnable; break; case PCI_MAX_LATENCY_FUNC_SET: pOpts->pciMaxLatFunc = (PCI_MAX_LAT_FUNC)pArg; break; case PCI_MAX_LATENCY_ARG_SET: pOpts->pciMaxLatPArg = pArg; break; case PCI_MSG_LOG_SET: pOpts->pciLogMsgFunc = (FUNCPTR)pArg; break; case PCI_MAX_BUS_SET: pOpts->maxBus = (int)pArg; break; case PCI_MAX_BUS_GET: (*(int *)pArg) = pOpts->maxBus; break; case PCI_CACHE_SIZE_SET: pOpts->cacheSize = (int)pArg; break; case PCI_CACHE_SIZE_GET: *(int *)pArg = pOpts->cacheSize; break; case PCI_MAX_LAT_ALL_SET: pOpts->maxLatency = (UINT)pArg; break; case PCI_MAX_LAT_ALL_GET: if ( pOpts->pciMaxLatFunc == NULL ) *(UINT *)pArg = pOpts->maxLatency; else *(UINT *)pArg = 0xffffffff; break; case PCI_AUTO_INT_ROUTE_SET: pOpts->autoIntRouting = (BOOL)pArg; break; case PCI_AUTO_INT_ROUTE_GET: *(BOOL *)pArg = pOpts->autoIntRouting; break; case PCI_MEM32_LOC_SET: pOpts->pciMem32 = (UINT)pArg; break; case PCI_MEM32_SIZE_SET: pOpts->pciMem32Size = (UINT)pArg; break; case PCI_MEM32_SIZE_GET: (*(UINT32 *)pArg) = pOpts->pciMem32Used; break; case PCI_MEMIO32_LOC_SET: pOpts->pciMemIo32 = (UINT)pArg; break; case PCI_MEMIO32_SIZE_SET: pOpts->pciMemIo32Size = (UINT)pArg; break; case PCI_MEMIO32_SIZE_GET: *(UINT *)pArg = pOpts->pciMemIo32Used; break; case PCI_IO32_LOC_SET: pOpts->pciIo32 = (UINT)pArg; break; case PCI_IO32_SIZE_SET: pOpts->pciIo32Size = (UINT)pArg; break; case PCI_IO32_SIZE_GET: *(UINT *)pArg = pOpts->pciIo32Used; break; case PCI_IO16_LOC_SET: pOpts->pciIo16 = (UINT)pArg; break; case PCI_IO16_SIZE_SET: pOpts->pciIo16Size = (UINT)pArg; break; case PCI_IO16_SIZE_GET: *(UINT *)pArg = pOpts->pciIo16Used; break; case PCI_INCLUDE_FUNC_SET: pOpts->includeRtn = (PCI_INCLUDE_FUNC)pArg; break; case PCI_INT_ASSIGN_FUNC_SET: pOpts->intAssignRtn = (PCI_INT_ASSIGN_FUNC)pArg; break; case PCI_BRIDGE_PRE_CONFIG_FUNC_SET: pOpts->bridgePreConfigInit = (PCI_BRIDGE_PRE_CONFIG_FUNC)pArg; break; case PCI_BRIDGE_POST_CONFIG_FUNC_SET: pOpts->bridgePostConfigInit = (PCI_BRIDGE_POST_CONFIG_FUNC)pArg; break; case PCI_ROLLCALL_FUNC_SET: pOpts->pciRollcallRtn = (FUNCPTR)pArg; break; case PCI_TEMP_SPACE_SET: pOpts->pFuncList = ((PCI_MEM_PTR *)pArg)->pMem; pOpts->numFuncListEntries = ((PCI_MEM_PTR *)pArg)->memSize / sizeof(PCI_LOC); break; default: errnoSet(EINVAL); return(ERROR); } return(OK); }#ifdef USE_PCI_SIMULATORvoid pciAutoConfigListShow(PCI_LOC *pLoc, int num) { while ( num >= 0 ) { PCI_AUTO_DEBUG_MSG("[%d,%d,%d] bar%d 0x%08x in %s space\n", pLoc->bus, pLoc->device, pLoc->function, 4,5,6); pLoc++; num--; } }#endif /* USE_PCI_SIMULATOR *//****************************************************************** pciAutoCfgFunc - the actual guts of pciAutoCfg().** The functions pciAutoConfig() and pciAutoCfg() are both* wrapper functions to go around this function. The actual* work is done by this function.** ALGORITHM:** Probe PCI config space and create a list of available PCI functions.* Call device exclusion function, if registered, to exclude/include device.* Disable all devices before we initialize any.* Allocate and assign PCI space to each device.* Calculate and set interrupt line value.* Initialize and enable each device.** RETURNS: OK, or ERROR if pCookie is not valid.**/LOCAL STATUS pciAutoCfgFunc ( void *pCookie /* cookie returned by pciAutoConfigLibInit() */ ) { PCI_AUTO_CONFIG_OPTS * pSystem; /* named for backward compatibility */ PCI_LOC* pPciList; /* Pointer to PCI include list */ int listSize; /* Size of PCI include list */ BOOL rollcallSuccess; /* has pciRollcallRtn() succeeded? */ /* Input parameter sanity checking */ if (pCookie == NULL) { errnoSet(EINVAL); return(ERROR); } pSystem = (PCI_AUTO_CONFIG_OPTS *)pCookie;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -