pvrsrv.c 源码详细分析
文件概述
这是PowerVR图形驱动的核心服务文件,实现了设备管理、电源管理、线程管理等核心功能。
核心数据结构
全局数据结构
static PVRSRV_DATA *gpsPVRSRVData; // 全局服务数据
static IMG_UINT32 g_ui32InitFlags; // 初始化标志
主要结构体关系图
核心功能模块
初始化流程
驱动初始化(PVRSRVCommonDriverInit)
关键代码段
PVRSRV_ERROR PVRSRVCommonDriverInit(void)
{
PVRSRV_ERROR eError;
PVRSRV_DATA *psPVRSRVData = NULL;
// 1. 检查是否已初始化
if (gpsPVRSRVData) {
return PVRSRV_ERROR_ALREADY_EXISTS;
}
// 2. 初始化设备无关功能
eError = DIInit();
eError = PVRSRVStatsInitialise();
eError = ServerBridgeInit();
// 3. 分配全局数据
psPVRSRVData = OSAllocZMemNoStats(sizeof(*gpsPVRSRVData));
gpsPVRSRVData = psPVRSRVData;
// 4. 创建设备节点列表锁
eError = OSWRLockCreate(&gpsPVRSRVData->hDeviceNodeListLock);
// 5. 初始化内存管理
eError = DevmemIntInit();
eError = PMRInit();
// 6. 创建清理线程
eError = _CleanupThreadPrepare(gpsPVRSRVData);
eError = OSThreadCreatePriority(&gpsPVRSRVData->hCleanupThread,
"xdxgpu_defer_free",
CleanupThread, ...);
// 7. 创建看门狗线程
eError = OSThreadCreatePriority(&gpsPVRSRVData->hDevicesWatchdogThread,
"xdxgpu_device_wdg",
DevicesWatchdogThread, ...);
return PVRSRV_OK;
}
设备创建流程(PVRSRVCommonDeviceCreate)
关键步骤
PVRSRV_ERROR PVRSRVCommonDeviceCreate(void *pvOSDevice,
IMG_INT32 i32KernelDeviceID,
PVRSRV_DEVICE_NODE **ppsDeviceNode)
{
// 1. 分配设备节点
psDeviceNode = OSAllocZMemNoStats(sizeof(*psDeviceNode));
// 2. 初始化清理队列
dllist_init(&psDeviceNode->sCleanupThreadWorkList);
// 3. 系统设备初始化
eError = SysDevInit(pvOSDevice, &psDevConfig);
// 4. 初始化物理堆
eError = PhysHeapInitDeviceHeaps(psDeviceNode, psDevConfig);
// 5. 初始化同步服务器
eError = SyncServerInit(psDeviceNode);
// 6. 注册RGX设备
eError = RGXRegisterDevice(psDeviceNode);
// 7. 初始化Checkpoint同步
eError = SyncCheckpointInit(psDeviceNode);
// 8. 注册调试请求
eError = PVRSRVRegisterDeviceDbgRequestNotify(...);
// 9. 初始化DVFS
eError = InitDVFS(psDeviceNode);
// 10. 添加到设备列表
List_PVRSRV_DEVICE_NODE_InsertTail(&psPVRSRVData->psDeviceNodeList,
psDeviceNode);
return PVRSRV_OK;
}
清理流程机制
清理线程状态
工作项管理
添加清理工作
void PVRSRVCleanupThreadAddWork_Int(PVRSRV_DEVICE_NODE *psDeviceNode,
PVRSRV_CLEANUP_THREAD_WORK *psData)
{
PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
// 1. 检查驱动卸载状态
if (psPVRSRVData->bUnload ||
psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_DESTRUCTING)
{
// 立即执行清理
eError = psData->pfnFree(psData->pvData);
return;
}
// 2. 检查设备是否禁用清理线程
if (_CleanupThreadDeviceDisabled(psDeviceNode))
{
// 立即清理
eError = psData->pfnFree(psData->pvData);
return;
}
// 3. 添加到工作列表
OSAtomicIncrement(&psPVRSRVData->i32NumCleanupItemsQueued);
OSSpinLockAcquire(psPVRSRVData->hCleanupThreadWorkListLock, uiFlags);
dllist_add_to_tail(&psDeviceNode->sCleanupThreadWorkList, &psData->sNode);
OSSpinLockRelease(psPVRSRVData->hCleanupThreadWorkListLock, uiFlags);
// 4. 唤醒清理线程
OSEventObjectSignal(psPVRSRVData->hCleanupEventObject);
}
处理工作列表
static IMG_BOOL _CleanupThreadProcessWorkList(PVRSRV_DATA *psPVRSRVData,
IMG_BOOL *pbUseHWTimeout)
{
DLLIST_NODE *psNodeIter;
PVRSRV_CLEANUP_THREAD_WORK *psData;
// 1. 获取工作列表的最后一项
psNodeLast = _CleanupThreadWorkListLast(psPVRSRVData);
if (psNodeLast == NULL) {
return IMG_FALSE;
}
// 2. 遍历处理工作项
do {
// 弹出工作项
psNodeIter = _CleanupThreadWorkListPop(psPVRSRVData, &psDeviceNode);
psData = IMG_CONTAINER_OF(psNodeIter, PVRSRV_CLEANUP_THREAD_WORK, sNode);
// 执行清理回调
eError = psData->pfnFree(psData->pvData);
if (eError != PVRSRV_OK) {
// 需要重试
if (psData->ui32RetryCount > 0) {
psData->ui32RetryCount--;
bNeedRetry = IMG_TRUE;
// 重新加入队列
dllist_add_to_tail(&psDeviceNode->sCleanupThreadWorkList,
psNodeIter);
} else {
// 重试次数用尽,丢弃
OSAtomicIncrement(&psPVRSRVData->i32NumCleanupItemsNotCompleted);
_CleanupThreadDecrementStats(psPVRSRVData, eCleanupType);
}
} else {
// 清理成功
OSAtomicDecrement(&psDeviceNode->i32NumCleanupItems);
_CleanupThreadDecrementStats(psPVRSRVData, eCleanupType);
}
} while (psNodeIter != psNodeLast);
return bNeedRetry;
}
看门狗线程
看门狗线程状态
支持无线睡眠
看门狗主循环
static void DevicesWatchdogThread(void *pvData)
{
PVRSRV_DATA *psPVRSRVData = pvData;
DWT_STATE eState = DWT_ST_INIT;
while (!psPVRSRVData->bUnload) {
switch (eState) {
case DWT_ST_INIT:
// 根据电源状态决定初始状态
if (_DwtIsPowerOn(psPVRSRVData)) {
eState = DWT_ST_SLEEP_POWERON;
} else {
eState = DWT_ST_SLEEP_POWEROFF;
}
break;
case DWT_ST_SLEEP_POWERON:
// 等待上电超时或信号
eSignal = _DwtWait(psPVRSRVData, hOSEvent, ui32OnTimeout);
switch (eSignal) {
case DWT_SIG_TIMEOUT:
// 检查设备健康状态
_DwtCheckHealthStatus(psPVRSRVData,
&ePreviousHealthStatus,
IMG_TRUE);
break;
case DWT_SIG_POWEROFF:
eState = DWT_ST_SLEEP_DEFERRED;
break;
}
break;
case DWT_ST_SLEEP_POWEROFF:
// 无限等待或长时间等待
eSignal = _DwtWait(psPVRSRVData, hOSEvent, ui32OffTimeout);
if (eSignal == DWT_SIG_POWERON) {
eState = DWT_ST_SLEEP_POWERON;
_DwtCheckHealthStatus(...);
}
break;
case DWT_ST_SLEEP_DEFERRED:
// 延迟状态,再次确认是否真的下电
eSignal = _DwtWait(psPVRSRVData, hOSEvent, ui32OnTimeout);
if (eSignal == DWT_SIG_TIMEOUT) {
eState = DWT_ST_SLEEP_POWEROFF;
}
break;
}
}
}
设备健康检测
static void DevicesWatchdogThread_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode,
va_list va)
{
PVRSRV_DEVICE_HEALTH_STATUS *pePreviousHealthStatus;
PVRSRV_DEVICE_HEALTH_STATUS eHealthStatus;
// 1. 只检查活动设备
if (psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_ACTIVE) {
return;
}
// 2. 阻塞直到设备解冻
PVRSRVBlockIfFrozen(psDeviceNode);
// 3. 更新设备健康状态
if (psDeviceNode->pfnUpdateHealthStatus != NULL) {
eError = psDeviceNode->pfnUpdateHealthStatus(psDeviceNode,
bCheckAfterTimePassed);
}
// 4. 读取健康状态
eHealthStatus = OSAtomicRead(&psDeviceNode->eHealthStatus);
// 5. 处理不健康状态
if (eHealthStatus != PVRSRV_DEVICE_HEALTH_STATUS_OK) {
if (eHealthStatus != *pePreviousHealthStatus) {
// 状态改变,进行调试转储
PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX,
NULL, NULL);
#if defined(SUPPORT_FW_HOST_SIDE_RECOVERY)
HandleFwHostSideRecovery(psDeviceNode);
#endif
}
}
// 6. 检查固件调试转储请求
eDebugDumpState = OSAtomicCompareExchange(
&psDeviceNode->eDebugDumpRequested,
PVRSRV_DEVICE_DEBUG_DUMP_CAPTURE,
PVRSRV_DEVICE_DEBUG_DUMP_NONE);
if (eDebugDumpState == PVRSRV_DEVICE_DEBUG_DUMP_CAPTURE) {
PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX,
NULL, NULL);
}
}
设备冻结/解冻机制
冻结流程
冻结实现
PVRSRV_ERROR PVRSRVDeviceFreeze(PVRSRV_DEVICE_NODE *psDevNode)
{
PVRSRV_ERROR eError;
IMG_BOOL bHasPowerLock = IMG_FALSE;
// 1. 验证设备节点有效性
// 遍历设备列表确认设备存在
// 2. 原子设置冻结标志
if (OSAtomicCompareExchange(&psDevNode->eFrozen, _NOT_FROZEN,
_FROZEN) == _FROZEN) {
return PVRSRV_ERROR_INVALID_PARAMS; // 已经冻结
}
// 3. 等待所有活动线程退出
while (OSAtomicRead(&psDevNode->iThreadsActive) > 0) {
OSReleaseThreadQuanta();
}
// 4. 尝试空闲设备(不下电)
eError = PVRSRVPowerLock(psDevNode);
if (eError == PVRSRV_OK) {
bHasPowerLock = IMG_TRUE;
eError = PVRSRVDeviceIdleRequestKM(psDevNode,
&PVRSRVDeviceIsDefaultStateOFF,
IMG_TRUE);
}
// 5. 失败则回滚
if (eError != PVRSRV_OK) {
OSAtomicExchange(&psDevNode->eFrozen, _NOT_FROZEN);
if (bHasPowerLock) {
PVRSRVPowerUnlock(psDevNode);
}
return eError;
}
// 6. 设置设备状态为冻结
PVRSRVDeviceSetState(psDevNode, PVRSRV_DEVICE_STATE_FROZEN);
OSAtomicIncrement(&psDevNode->iTotalFreezes);
if (bHasPowerLock) {
PVRSRVPowerUnlock(psDevNode);
}
return PVRSRV_OK;
}
解冻流程
PVRSRV_ERROR PVRSRVDeviceThaw(PVRSRV_DEVICE_NODE *psDevNode)
{
// 1. 验证设备节点
// 2. 原子清除冻结标志
if (OSAtomicCompareExchange(&psDevNode->eFrozen, _FROZEN,
_NOT_FROZEN) == _NOT_FROZEN) {
return PVRSRV_ERROR_INVALID_PARAMS; // 未冻结
}
// 3. 恢复设备状态
PVRSRVDeviceSetState(psDevNode, PVRSRV_DEVICE_STATE_ACTIVE);
// 4. 取消空闲请求并上电
eError = PVRSRVPowerLock(psDevNode);
if (eError == PVRSRV_OK) {
PVRSRVDeviceIdleCancelRequestKM(psDevNode);
PVRSRVPowerUnlock(psDevNode);
} else {
// 强制上电
PVRSRVSetDeviceSystemPowerState(psDevNode,
PVRSRV_SYS_POWER_STATE_ON,
PVRSRV_POWER_FLAGS_NONE);
}
// 5. 唤醒所有等待线程
while (OSAtomicRead(&psDevNode->iFreezeCount) > 0) {
OSEventObjectSignal(psDevNode->hDeviceThreadEvObj);
OSSleepms(1U);
}
// 6. 触发队列重调度
PVRSRVCheckStatus(NULL);
return PVRSRV_OK;
}
电源管理
轮询等待机制
PVRSRV_ERROR PVRSRVPollForValueKM(PVRSRV_DEVICE_NODE *psDevNode,
volatile IMG_UINT32 __iomem *pui32LinMemAddr,
IMG_UINT32 ui32Value,
IMG_UINT32 ui32Mask,
POLL_FLAGS ePollFlags,
PFN_INVALIDATE_CACHEFUNC pfnFwInvalidate)
{
IMG_UINT32 ui32ActualValue;
// 循环轮询,最多MAX_HW_TIME_US
LOOP_UNTIL_TIMEOUT_US(MAX_HW_TIME_US) {
// 1. 失效缓存(如果需要)
if (pfnFwInvalidate) {
pfnFwInvalidate((const volatile void __force *)pui32LinMemAddr,
sizeof(*pui32LinMemAddr),
PVRSRV_CACHE_OP_INVALIDATE);
}
// 2. 读取实际值
ui32ActualValue = OSReadHWReg32((void __iomem *)pui32LinMemAddr, 0)
& ui32Mask;
// 3. 检查是否匹配
if (ui32ActualValue == ui32Value) {
return PVRSRV_OK;
}
// 4. 检查服务状态
if (gpsPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK) {
return PVRSRV_ERROR_TIMEOUT;
}
// 5. 等待一段时间
if (ui32PollPeriodus <= ONE_MSEC_IN_USECS) {
OSWaitus(ui32PollPeriodus);
} else {
OSSleepms(ui32PollPeriodus / ONE_MSEC_IN_USECS);
}
} END_LOOP_UNTIL_TIMEOUT_US();
// 超时处理
if (BITMASK_HAS(ePollFlags, POLL_FLAG_LOG_ERROR)) {
PVR_DPF((PVR_DBG_ERROR, "PollForValueKM: Timeout"));
}
if (BITMASK_HAS(ePollFlags, POLL_FLAG_DEBUG_DUMP)) {
PVRSRVDebugRequest(psDevNode, DEBUG_REQUEST_VERBOSITY_MAX,
NULL, NULL);
}
return PVRSRV_ERROR_TIMEOUT;
}
事件等待机制
PVRSRV_ERROR PVRSRVWaitForValueKM(volatile IMG_UINT32 __iomem *pui32LinMemAddr,
IMG_UINT32 ui32Value,
IMG_UINT32 ui32Mask,
PFN_INVALIDATE_CACHEFUNC pfnFwInvalidate)
{
PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
IMG_HANDLE hOSEvent;
// 1. 打开全局事件对象
eError = OSEventObjectOpen(psPVRSRVData->hGlobalEventObject, &hOSEvent);
// 2. 循环等待
LOOP_UNTIL_TIMEOUT_US(MAX_HW_TIME_US) {
// 检查值
if (pfnFwInvalidate) {
pfnFwInvalidate(...);
}
ui32ActualValue = OSReadDeviceMem32(pui32LinMemAddr) & ui32Mask;
if (ui32ActualValue == ui32Value) {
eError = PVRSRV_OK;
break;
}
// 检查服务状态
if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK) {
eError = PVRSRV_ERROR_NOT_READY;
break;
}
// 等待事件
eErrorWait = OSEventObjectWait(hOSEvent);
} END_LOOP_UNTIL_TIMEOUT_US();
OSEventObjectClose(hOSEvent);
// 3. 更新超时统计
if (eError == PVRSRV_OK) {
psPVRSRVData->ui32GEOConsecutiveTimeouts = 0;
} else if (eError == PVRSRV_ERROR_TIMEOUT) {
psPVRSRVData->ui32GEOConsecutiveTimeouts++;
}
return eError;
}
设备销毁流程
关键实现
void PVRSRVCommonDeviceDestroy(PVRSRV_DEVICE_NODE *psDeviceNode)
{
// 1. 标记设备正在清理
PVRSRVDeviceSetState(psDeviceNode, PVRSRV_DEVICE_STATE_DEINIT);
// 2. 禁用清理线程并等待完成
_CleanupThreadDisableForDevice(psDeviceNode);
PVRSRVCleanupThreadWaitForDevice(psDeviceNode);
// 3. 从设备列表中移除
OSWRLockAcquireWrite(psPVRSRVData->hDeviceNodeListLock);
List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
psPVRSRVData->ui32RegisteredDevices--;
OSWRLockReleaseWrite(psPVRSRVData->hDeviceNodeListLock);
// 4. 设置状态为销毁中
PVRSRVDeviceSetState(psDeviceNode, PVRSRV_DEVICE_STATE_DESTRUCTING);
// 5. 注销DVFS
#if defined(SUPPORT_LINUX_DVFS)
UnregisterDVFSDevice(psDeviceNode);
#endif
// 6. 清理调试系统
pvr_apphint_device_unregister(psDeviceNode);
DebugCommonDeInitDevice(psDeviceNode);
// 7. 销毁同步上下文
if (psDeviceNode->hSyncCheckpointContext) {
SyncCheckpointContextDestroy(psDeviceNode->hSyncCheckpointContext);
}
if (psDeviceNode->hSyncPrimContext) {
SyncPrimFree(psDeviceNode->psMMUCacheSyncPrim);
SyncPrimContextDestroy(psDeviceNode->hSyncPrimContext);
}
// 8. 电源管理:强制下电
eError = PVRSRVPowerLock(psDeviceNode);
if (eError == PVRSRV_OK) {
// 强制设备空闲
PVRSRVDeviceIdleRequestKM(psDeviceNode, NULL, IMG_TRUE);
// 强制下电
PVRSRVSetDevicePowerStateKM(psDeviceNode,
PVRSRV_DEV_POWER_STATE_OFF,
PVRSRV_POWER_FLAGS_FORCED);
PVRSRVPowerUnlock(psDeviceNode);
}
// 9. 清理DVFS
#if defined(SUPPORT_LINUX_DVFS)
DeinitDVFS(psDeviceNode);
#endif
// 10. 注销调试回调
if (psDeviceNode->hDbgReqNotify) {
PVRSRVUnregisterDeviceDbgRequestNotify(psDeviceNode->hDbgReqNotify);
}
// 11. 清理同步检查点
SyncCheckpointDeinit(psDeviceNode);
// 12. MMU清理
MMU_DeInitDevice(psDeviceNode);
// 13. RGX设备清理
#if defined(SUPPORT_RGX)
DevDeInitRGX(psDeviceNode);
SyncServerDeinit(psDeviceNode);
#endif
// 14. DMA缓存清理
#if defined(SUPPORT_DMA_TRANSFER)
PVRSRVDeInitDMACache(psDeviceNode);
#endif
// 15. PMR清理
#if defined(SUPPORT_PMR_DEFERRED_FREE)
PMRDeInitDevice(psDeviceNode);
#endif
// 16. 物理堆清理
PhysHeapDeInitDeviceHeaps(psDeviceNode);
// 17. 电源锁清理
PVRSRVPowerLockDeInit(psDeviceNode);
// 18. 注销设备调试表
PVRSRVUnregisterDeviceDbgTable(psDeviceNode);
// 19. 销毁页面故障通知锁
if (psDeviceNode->hPageFaultNotifyLock) {
OSWRLockDestroy(psDeviceNode->hPageFaultNotifyLock);
}
// 20. 销毁连接锁
if (psDeviceNode->hConnectionsLock) {
OSLockDestroy(psDeviceNode->hConnectionsLock);
}
// 21. 销毁设备线程事件对象
if (psDeviceNode->hDeviceThreadEvObj) {
OSEventObjectClose(psDeviceNode->hDeviceFreezeThaw);
OSEventObjectDestroy(psDeviceNode->hDeviceThreadEvObj);
}
// 22. 系统设备清理
psDeviceNode->psDevConfig->psDevNode = NULL;
SysDevDeInit(psDeviceNode->psDevConfig);
// 23. 释放设备节点内存
OSFreeMemNoStats(psDeviceNode);
}
辅助功能模块
物理堆管理
PHYS_HEAP_CONFIG* PVRSRVFindPhysHeapConfig(PVRSRV_DEVICE_CONFIG *psDevConfig,
PHYS_HEAP_USAGE_FLAGS ui32Flags)
{
IMG_UINT32 i;
// 遍历所有物理堆配置
for (i = 0; i < psDevConfig->ui32PhysHeapCount; i++) {
if (BITMASK_HAS(psDevConfig->pasPhysHeaps[i].ui32UsageFlags, ui32Flags)) {
return &psDevConfig->pasPhysHeaps[i];
}
}
return NULL;
}
4.2 系统特性查询
// 检查系统是否支持缓存窥探
IMG_BOOL PVRSRVSystemHasCacheSnooping(PVRSRV_DEVICE_CONFIG *psDevConfig)
{
if ((psDevConfig->eCacheSnoopingMode != PVRSRV_DEVICE_SNOOP_NONE) &&
(psDevConfig->eCacheSnoopingMode != PVRSRV_DEVICE_SNOOP_EMULATED)) {
return IMG_TRUE;
}
return IMG_FALSE;
}
// 检查窥探是否是模拟的
IMG_BOOL PVRSRVSystemSnoopingIsEmulated(PVRSRV_DEVICE_CONFIG *psDevConfig)
{
return (psDevConfig->eCacheSnoopingMode == PVRSRV_DEVICE_SNOOP_EMULATED);
}
// 检查CPU缓存窥探
IMG_BOOL PVRSRVSystemSnoopingOfCPUCache(PVRSRV_DEVICE_CONFIG *psDevConfig)
{
if ((psDevConfig->eCacheSnoopingMode == PVRSRV_DEVICE_SNOOP_CPU_ONLY) ||
(psDevConfig->eCacheSnoopingMode == PVRSRV_DEVICE_SNOOP_CROSS)) {
return IMG_TRUE;
}
return IMG_FALSE;
}
// 检查是否有不可映射的本地内存
IMG_BOOL PVRSRVSystemHasNonMappableLocalMemory(PVRSRV_DEVICE_CONFIG *psDevConfig)
{
return psDevConfig->bHasNonMappableLocalMemory;
}
设备查找
// 通过内部ID获取设备实例
PVRSRV_DEVICE_NODE *PVRSRVGetDeviceInstance(IMG_UINT32 uiInstance)
{
PVRSRV_DEVICE_NODE *psDevNode;
if (uiInstance >= gpsPVRSRVData->ui32RegisteredDevices) {
return NULL;
}
OSWRLockAcquireRead(gpsPVRSRVData->hDeviceNodeListLock);
for (psDevNode = gpsPVRSRVData->psDeviceNodeList;
psDevNode != NULL; psDevNode = psDevNode->psNext) {
if (uiInstance == psDevNode->sDevId.ui32InternalID) {
break;
}
}
OSWRLockReleaseRead(gpsPVRSRVData->hDeviceNodeListLock);
return psDevNode;
}
// 通过内核设备ID获取设备实例
PVRSRV_DEVICE_NODE *PVRSRVGetDeviceInstanceByKernelDevID(IMG_INT32 i32OSInstance)
{
PVRSRV_DEVICE_NODE *psDevNode;
OSWRLockAcquireRead(gpsPVRSRVData->hDeviceNodeListLock);
for (psDevNode = gpsPVRSRVData->psDeviceNodeList;
psDevNode != NULL; psDevNode = psDevNode->psNext) {
if (i32OSInstance == psDevNode->sDevId.i32KernelDeviceID) {
break;
}
}
OSWRLockReleaseRead(gpsPVRSRVData->hDeviceNodeListLock);
return psDevNode;
}
虚拟化支持
虚拟化模式配置
static void _InitDefaultVzDriverMode(PVRSRV_DATA *psPVRSRVData,
void *pvAppHintState)
{
char *pszMode, pszModeAppHint[PVRVZMODE_BUFFER_SIZE];
PVRSRV_DRIVER_MODE aeInitModes[PVRSRV_MAX_DEVICES];
IMG_UINT ui32Dev;
// 1. 初始化默认模式
for (ui32Dev = 0; ui32Dev < PVRSRV_MAX_DEVICES; ui32Dev++) {
aeInitModes[ui32Dev] = DRIVER_MODE_DEFAULT;
}
// 2. 读取AppHint配置
bRet = OSGetAppHintSTRING(APPHINT_NO_DEVICE,
pvAppHintState,
DriverMode,
pszDefault,
pszModeAppHint,
PVRVZMODE_BUFFER_SIZE);
// 3. 解析模式字符串
pszMode = pszModeAppHint;
ui32Dev = 0;
while (*pszMode && (ui32Dev < PVRSRV_MAX_DEVICES)) {
// 跳过逗号
while (*pszMode == ',') {
pszMode++;
}
// 匹配模式字符串
for (eMode = DRIVER_MODE_NATIVE; eMode <= DRIVER_MODE_DEFAULT; eMode++) {
if (OSStringNCompare(pszMode,
asModeStrings[eMode],
OSStringLength(asModeStrings[eMode])) == 0) {
aeInitModes[ui32Dev] = eMode;
}
}
// 前进到下一个模式
while ((*pszMode != '\0') && (*pszMode != ',')) {
pszMode++;
}
ui32Dev++;
}
// 4. 保存解析的模式
for (ui32Dev = 0; ui32Dev < PVRSRV_MAX_DEVICES; ui32Dev++) {
psPVRSRVData->aeModuleParamDriverMode[ui32Dev] = aeInitModes[ui32Dev];
}
}
// 获取设备的虚拟化模式
PVRSRV_DRIVER_MODE PVRSRVGetVzModeByDevNum(IMG_UINT32 ui32DevNum)
{
PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
PVRSRV_DRIVER_MODE eRetMode = DRIVER_MODE_NATIVE;
PVRSRV_DEVICE_NODE *psDevNode;
OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock);
for (psDevNode = psPVRSRVData->psDeviceNodeList;
psDevNode != NULL;
psDevNode = psDevNode->psNext) {
if (psDevNode->sDevId.ui32InternalID == ui32DevNum) {
eRetMode = psDevNode->psDevConfig->eDriverMode;
break;
}
}
OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock);
return eRetMode;
}
虚拟化锁管理
// 设备创建时的虚拟化锁
void PVRSRVDeviceCreationPvzLock(void)
{
PvzServerLockAcquire();
}
void PVRSRVDeviceCreationPvzUnlock(void)
{
PvzServerLockRelease();
}
// 设备初始化时的虚拟化锁
void PVRSRVDeviceInitPvzLock(PVRSRV_DEVICE_NODE *psDeviceNode)
{
if (!PVRSRV_VZ_MODE_IS(GUEST, DEVNODE, psDeviceNode)) {
PvzServerLockAcquire();
}
}
void PVRSRVDeviceInitPvzUnlock(PVRSRV_DEVICE_NODE *psDeviceNode)
{
if (!PVRSRV_VZ_MODE_IS(GUEST, DEVNODE, psDeviceNode)) {
PvzServerLockRelease();
}
}
HWPerf主机线程
HWPerf线程管理
#if defined(SUPPORT_RGX)
static void HWPerfPeriodicHostEventsThread(void *pvData)
{
PVRSRV_DATA *psPVRSRVData = pvData;
IMG_HANDLE hOSEvent;
// 打开事件对象
eError = OSEventObjectOpen(psPVRSRVData->hHWPerfHostPeriodicEvObj,
&hOSEvent);
// 主循环
while (!psPVRSRVData->bUnload && !psPVRSRVData->bHWPerfHostThreadStop) {
PVRSRV_DEVICE_NODE *psDeviceNode;
IMG_BOOL bInfiniteSleep = IMG_TRUE;
// 等待超时或信号
eError = OSEventObjectWaitKernel(hOSEvent,
(IMG_UINT64)psPVRSRVData->ui32HWPerfHostThreadTimeout * 1000);
if (eError == PVRSRV_OK &&
(psPVRSRVData->bUnload || psPVRSRVData->bHWPerfHostThreadStop)) {
break;
}
// 遍历所有设备
for (psDeviceNode = psPVRSRVData->psDeviceNodeList;
psDeviceNode != NULL;
psDeviceNode = psDeviceNode->psNext) {
PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
if (psDevInfo == NULL || psDevInfo->hHWPerfHostStream == NULL) {
continue;
}
// 检查流是否打开以供读取
if (TLStreamIsOpenForReading(psDevInfo->hHWPerfHostStream)) {
bInfiniteSleep = IMG_FALSE;
// 发送内存使用信息事件
RGXSRV_HWPERF_HOST_INFO(psDevInfo,
RGX_HWPERF_INFO_EV_MEM64_USAGE);
}
}
// 调整超时时间
if (bInfiniteSleep) {
#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP)
psPVRSRVData->ui32HWPerfHostThreadTimeout = INFINITE_SLEEP_TIMEOUT;
#else
psPVRSRVData->ui32HWPerfHostThreadTimeout = 60 * 60 * 8 * 1000;
#endif
}
}
OSEventObjectClose(hOSEvent);
}
// 创建HWPerf主机线程
PVRSRV_ERROR PVRSRVCreateHWPerfHostThread(IMG_UINT32 ui32Timeout)
{
PVRSRV_ERROR eError = PVRSRV_OK;
if (!ui32Timeout) {
return PVRSRV_ERROR_INVALID_PARAMS;
}
OSLockAcquire(gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock);
// 只创建一次
if (gpsPVRSRVData->hHWPerfHostPeriodicThread == NULL) {
// 创建事件对象
eError = OSEventObjectCreate("PVRSRV_HWPERFHOSTPERIODIC_EVENTOBJECT",
&gpsPVRSRVData->hHWPerfHostPeriodicEvObj);
if (eError == PVRSRV_OK) {
gpsPVRSRVData->bHWPerfHostThreadStop = IMG_FALSE;
gpsPVRSRVData->ui32HWPerfHostThreadTimeout = ui32Timeout;
// 创建线程
eError = OSThreadCreate(&gpsPVRSRVData->hHWPerfHostPeriodicThread,
"pvr_hwperf_host",
HWPerfPeriodicHostEventsThread,
NULL, IMG_TRUE, gpsPVRSRVData);
}
} else {
// 线程已存在,更新超时并唤醒
gpsPVRSRVData->ui32HWPerfHostThreadTimeout = ui32Timeout;
eError = OSEventObjectSignal(gpsPVRSRVData->hHWPerfHostPeriodicEvObj);
}
OSLockRelease(gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock);
return eError;
}
// 销毁HWPerf主机线程
PVRSRV_ERROR PVRSRVDestroyHWPerfHostThread(void)
{
PVRSRV_ERROR eError = PVRSRV_OK;
OSLockAcquire(gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock);
if (gpsPVRSRVData->hHWPerfHostPeriodicThread) {
if (gpsPVRSRVData->hHWPerfHostPeriodicEvObj) {
gpsPVRSRVData->bHWPerfHostThreadStop = IMG_TRUE;
eError = OSEventObjectSignal(gpsPVRSRVData->hHWPerfHostPeriodicEvObj);
}
// 循环尝试销毁线程
LOOP_UNTIL_TIMEOUT_US(OS_THREAD_DESTROY_TIMEOUT_US) {
eError = OSThreadDestroy(gpsPVRSRVData->hHWPerfHostPeriodicThread);
if (PVRSRV_OK == eError) {
gpsPVRSRVData->hHWPerfHostPeriodicThread = NULL;
break;
}
OSWaitus(OS_THREAD_DESTROY_TIMEOUT_US/OS_THREAD_DESTROY_RETRY_COUNT);
} END_LOOP_UNTIL_TIMEOUT_US();
if (gpsPVRSRVData->hHWPerfHostPeriodicEvObj) {
eError = OSEventObjectDestroy(gpsPVRSRVData->hHWPerfHostPeriodicEvObj);
gpsPVRSRVData->hHWPerfHostPeriodicEvObj = NULL;
}
}
OSLockRelease(gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock);
return eError;
}
#endif
AutoVz看门狗线程
#if defined(SUPPORT_AUTOVZ)
static void AutoVzWatchdogThread_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
{
if (psDeviceNode->pfnUpdateAutoVzWatchdog != NULL) {
psDeviceNode->pfnUpdateAutoVzWatchdog(psDeviceNode);
}
}
static void AutoVzWatchdogThread(void *pvData)
{
PVRSRV_DATA *psPVRSRVData = pvData;
IMG_HANDLE hOSEvent;
// 打开事件对象
eError = OSEventObjectOpen(psPVRSRVData->hAutoVzWatchdogEvObj, &hOSEvent);
while (!psPVRSRVData->bUnload) {
// 等待周期性超时
eError = OSEventObjectWaitKernel(hOSEvent,
(IMG_UINT64)PVR_AUTOVZ_WDG_KICK_PERIOD_MS * 1000);
// 更新所有设备的AutoVz看门狗
List_PVRSRV_DEVICE_NODE_ForEach(psPVRSRVData->psDeviceNodeList,
AutoVzWatchdogThread_ForEachCb);
}
OSEventObjectClose(hOSEvent);
}
#endif
调试和诊断
调试请求处理
static void _SysDebugRequestNotify(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle,
IMG_UINT32 ui32VerbLevel,
DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
void *pvDumpDebugFile)
{
PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*)hDebugRequestHandle;
PVR_DUMPDEBUG_LOG("------[ System Summary Device ID:%d ]------",
psDeviceNode->sDevId.ui32InternalID);
// 输出电源状态
switch (psDeviceNode->eCurrentSysPowerState) {
case PVRSRV_SYS_POWER_STATE_OFF:
PVR_DUMPDEBUG_LOG("Device System Power State: OFF");
break;
case PVRSRV_SYS_POWER_STATE_ON:
PVR_DUMPDEBUG_LOG("Device System Power State: ON");
break;
default:
PVR_DUMPDEBUG_LOG("Device System Power State: UNKNOWN (%d)",
psDeviceNode->eCurrentSysPowerState);
break;
}
// 输出超时配置
PVR_DUMPDEBUG_LOG("MaxHWTOut: %dus, WtTryCt: %d, WDGTOut(on,off): (%dms,%dms)",
MAX_HW_TIME_US, WAIT_TRY_COUNT,
DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT,
DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT);
// 如果设备上电,调用系统层调试信息
if (psDeviceNode->eCurrentSysPowerState == PVRSRV_SYS_POWER_STATE_ON) {
SysDebugInfo(psDeviceNode->psDevConfig, pfnDumpDebugPrintf,
pvDumpDebugFile);
}
}
清理线程调试信息
static void CleanupThreadDumpInfo(DUMPDEBUG_PRINTF_FUNC* pfnDumpDebugPrintf,
void *pvDumpDebugFile)
{
IMG_CHAR acCleanupString[CLEANUP_STRING_SUMMARY_MAX_LEN];
PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
PVR_DUMPDEBUG_LOG(" Number of deferred cleanup items: %s",
_ConcatCleanupString(acCleanupString));
PVR_DUMPDEBUG_LOG(" Number of deferred cleanup items dropped after "
"retry limit reached : %d",
OSAtomicRead(&psPVRSRVData->i32NumCleanupItemsNotCompleted));
}
// 拼接清理字符串
static IMG_CHAR *_ConcatCleanupString(IMG_CHAR *cleanupString)
{
IMG_UINT32 uiLoop;
IMG_UINT32 strSize = CLEANUP_STRING_SUMMARY_MAX_LEN;
PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
// 输出总数
OSSNPrintf(cleanupString, CLEANUP_QUEUE_TOTAL_DPF_MAX_SIZE,
CLEANUP_QUEUE_TOTAL_DPF,
OSAtomicRead(&psPVRSRVData->i32NumCleanupItemsQueued));
// 输出各类型数量
for (uiLoop = PVRSRV_CLEANUP_TYPE_CONNECTION;
(strSize > CLEANUP_TYPE_ITEM_DPF_MAX_SIZE) &&
(uiLoop < PVRSRV_CLEANUP_TYPE_LAST);
uiLoop++) {
IMG_CHAR acTempQueued[CLEANUP_TYPE_ITEM_DPF_MAX_SIZE];
OSSNPrintf(acTempQueued, CLEANUP_TYPE_ITEM_DPF_MAX_SIZE,
CLEANUP_TYPE_ITEM_DPF,
PVRSRVGetCleanupName(uiLoop),
OSAtomicRead(&psPVRSRVData->i32CleanupItemTypes[uiLoop]));
OSStringLCat(cleanupString, acTempQueued, strSize);
}
return cleanupString;
}
完整的驱动生命周期
整体架构图
完整初始化序列
关键数据流
清理工作流
电源状态转换
重要常量和配置
// 超时配置
#define CLEANUP_THREAD_WAIT_RETRY_TIMEOUT 100000ULL // 100ms
#define CLEANUP_THREAD_WAIT_SLEEP_TIMEOUT 28800000000ULL // 8小时
#define CLEANUP_THREAD_UNLOAD_RETRY 4
#define DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT
// 设备看门狗超时配置
#define DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT // 设备上电时看门狗检查间隔
#define DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT // 设备下电时看门狗检查间隔
// 线程销毁超时
#define OS_THREAD_DESTROY_TIMEOUT_US // 线程销毁超时时间
#define OS_THREAD_DESTROY_RETRY_COUNT // 线程销毁重试次数
// 硬件超时
#define MAX_HW_TIME_US // 最大硬件操作等待时间
#define WAIT_TRY_COUNT // 轮询重试次数
// 清理线程超时
#define OS_CLEANUP_THREAD_TIMEOUT_US // 清理线程超时
错误处理机制
错误处理流程
设备错误恢复
#if defined(SUPPORT_FW_HOST_SIDE_RECOVERY)
static PVRSRV_ERROR HandleFwHostSideRecovery(PVRSRV_DEVICE_NODE *psDeviceNode)
{
PVRSRV_ERROR eError = PVRSRV_OK;
PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice;
DLLIST_NODE *psNode, *psNext;
IMG_UINT32 ui32CtxIdx = 0U;
IMG_UINT32 ui32Nodes = 0U;
OSWRLockAcquireRead(psDevInfo->hCommonCtxtListLock);
// 1. 统计活动上下文数量
dllist_foreach_node(&psDevInfo->sCommonCtxtListHead, psNode, psNext) {
++ui32Nodes;
}
// 2. 如果有活动上下文,准备重新激活它们
if (ui32Nodes > 0U) {
// 释放旧的上下文缓冲区
if (psDevInfo->psRGXFWIfActiveContextBufDesc) {
DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfActiveContextBufDesc);
DevmemFwUnmapAndFree(psDevInfo,
psDevInfo->psRGXFWIfActiveContextBufDesc);
psDevInfo->psRGXFWIfActiveContextBufDesc = NULL;
}
// 分配新的活动上下文缓冲区
eError = RGXSetupFwAllocation(psDevInfo,
RGX_FWSHAREDMEM_MAIN_ALLOCFLAGS,
(ui32Nodes + 1) * sizeof(RGXFWIF_ACTIVE_CONTEXT_BUF_DATA),
"FwSysActiveContextBufData",
&psDevInfo->psRGXFWIfActiveContextBufDesc,
(void *)&psDevInfo->psRGXFWIfSysInit->sActiveContextBufBase.ui32Addr,
(void **)&psDevInfo->psRGXFWIfActiveContextBuf,
RFW_FWADDR_NOREF_FLAG);
PVR_LOG_GOTO_IF_ERROR(eError, "RGXSetupFwAllocation", Error);
// 填充需要重新激活的上下文列表
dllist_foreach_node_backwards(&psDevInfo->sCommonCtxtListHead,
psNode, psNext) {
psDevInfo->psRGXFWIfActiveContextBuf[ui32CtxIdx].psContext =
RGXGetFWCommonContextAddrFromServerCommonCtx(psDevInfo, psNode);
++ui32CtxIdx;
}
// 添加终止标记
psDevInfo->psRGXFWIfActiveContextBuf[ui32CtxIdx].psContext.ui32Addr = 0;
}
OSWRLockReleaseRead(psDevInfo->hCommonCtxtListLock);
// 3. 强制设备下电(固件已无响应)
eError = PVRSRVSetDeviceCurrentPowerState(psDeviceNode->psPowerDev,
PVRSRV_DEV_POWER_STATE_OFF);
PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVSetDeviceCurrentPowerState OFF", Error);
// 4. 设置固件恢复模式标志
psDevInfo->psRGXFWIfSysInit->bFwHostRecoveryMode = IMG_TRUE;
// 5. 刷新缓存
RGXFwSharedMemCacheOpPtr(psDevInfo->psRGXFWIfSysInit, FLUSH);
// 6. 重新上电,复位GPU和固件
OSLockAcquire(psDeviceNode->hPowerLock);
eError = PVRSRVSetDevicePowerStateKM(psDeviceNode,
PVRSRV_DEV_POWER_STATE_ON,
PVRSRV_POWER_FLAGS_NONE);
PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVSetDevicePowerStateKM ON", Error);
OSLockRelease(psDeviceNode->hPowerLock);
Error:
return eError;
}
#endif
AppHint处理
AppHint回调函数
#if defined(SUPPORT_RGX)
// 设置设备标志
static PVRSRV_ERROR _SetDeviceFlag(const PVRSRV_DEVICE_NODE *psDevice,
const void *psPrivate, IMG_BOOL bValue)
{
PVRSRV_ERROR eResult = PVRSRV_OK;
IMG_UINT32 ui32Flag = (IMG_UINT32)((uintptr_t)psPrivate);
PVR_RETURN_IF_INVALID_PARAM(ui32Flag);
PVR_RETURN_IF_FALSE(psDevice != APPHINT_OF_DRIVER_NO_DEVICE,
PVRSRV_ERROR_INVALID_PARAMS);
eResult = RGXSetDeviceFlags((PVRSRV_RGXDEV_INFO *)psDevice->pvDevice,
ui32Flag, bValue);
return eResult;
}
// 读取设备标志
static PVRSRV_ERROR _ReadDeviceFlag(const PVRSRV_DEVICE_NODE *psDevice,
const void *psPrivate, IMG_BOOL *pbValue)
{
PVRSRV_ERROR eResult = PVRSRV_OK;
IMG_UINT32 ui32Flag = (IMG_UINT32)((uintptr_t)psPrivate);
IMG_UINT32 ui32State;
PVR_RETURN_IF_INVALID_PARAM(ui32Flag);
PVR_RETURN_IF_FALSE(psDevice != APPHINT_OF_DRIVER_NO_DEVICE,
PVRSRV_ERROR_INVALID_PARAMS);
eResult = RGXGetDeviceFlags((PVRSRV_RGXDEV_INFO *)psDevice->pvDevice,
&ui32State);
if (PVRSRV_OK == eResult) {
*pbValue = (ui32State & ui32Flag) ? IMG_TRUE : IMG_FALSE;
}
return eResult;
}
// 设置状态标志
static PVRSRV_ERROR _SetStateFlag(const PVRSRV_DEVICE_NODE *psDevice,
const void *psPrivate, IMG_BOOL bValue)
{
PVRSRV_ERROR eResult = PVRSRV_OK;
IMG_UINT32 ui32Flag = (IMG_UINT32)((uintptr_t)psPrivate);
PVR_RETURN_IF_INVALID_PARAM(ui32Flag);
PVR_RETURN_IF_FALSE(psDevice != APPHINT_OF_DRIVER_NO_DEVICE,
PVRSRV_ERROR_INVALID_PARAMS);
eResult = RGXStateFlagCtrl((PVRSRV_RGXDEV_INFO *)psDevice->pvDevice,
ui32Flag, NULL, bValue);
return eResult;
}
// 读取状态标志
static PVRSRV_ERROR _ReadStateFlag(const PVRSRV_DEVICE_NODE *psDevice,
const void *psPrivate, IMG_BOOL *pbValue)
{
IMG_UINT32 ui32Flag = (IMG_UINT32)((uintptr_t)psPrivate);
IMG_UINT32 ui32State;
PVRSRV_RGXDEV_INFO *psDevInfo;
PVR_RETURN_IF_INVALID_PARAM(ui32Flag);
PVR_RETURN_IF_FALSE(psDevice != APPHINT_OF_DRIVER_NO_DEVICE,
PVRSRV_ERROR_INVALID_PARAMS);
psDevInfo = (PVRSRV_RGXDEV_INFO *)psDevice->pvDevice;
// 失效缓存并读取状态
RGXFwSharedMemCacheOpValue(psDevInfo->psRGXFWIfFwSysData->ui32ConfigFlags,
INVALIDATE);
ui32State = psDevInfo->psRGXFWIfFwSysData->ui32ConfigFlags;
if (pbValue) {
*pbValue = (ui32State & ui32Flag) ? IMG_TRUE : IMG_FALSE;
}
return PVRSRV_OK;
}
#endif
AppHint注册
// 在设备初始化完成后注册AppHint处理器
if (bInitSuccessful && (eError == PVRSRV_OK)) {
RGXInitDeviceInfo(psDeviceNode);
if (!PVRSRV_VZ_MODE_IS(GUEST, DEVNODE, psDeviceNode)) {
// 注册状态标志AppHint
PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_DisableClockGating,
_ReadStateFlag, _SetStateFlag,
APPHINT_OF_DRIVER_NO_DEVICE,
(void*)((uintptr_t)RGXFWIF_INICFG_DISABLE_CLKGATING_EN));
PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_DisableDMOverlap,
_ReadStateFlag, _SetStateFlag,
APPHINT_OF_DRIVER_NO_DEVICE,
(void*)((uintptr_t)RGXFWIF_INICFG_DISABLE_DM_OVERLAP));
PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_AssertOnHWRTrigger,
_ReadStateFlag, _SetStateFlag,
psDeviceNode,
(void*)((uintptr_t)RGXFWIF_INICFG_ASSERT_ON_HWR_TRIGGER));
PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_AssertOutOfMemory,
_ReadStateFlag, _SetStateFlag,
psDeviceNode,
(void*)((uintptr_t)RGXFWIF_INICFG_ASSERT_ON_OUTOFMEMORY));
PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_CheckMList,
_ReadStateFlag, _SetStateFlag,
psDeviceNode,
(void*)((uintptr_t)RGXFWIF_INICFG_CHECK_MLIST_EN));
}
// 注册设备标志AppHint
PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_DisableFEDLogging,
_ReadDeviceFlag, _SetDeviceFlag,
psDeviceNode,
(void*)((uintptr_t)RGXKM_DEVICE_STATE_DISABLE_DW_LOGGING_EN));
PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_ZeroFreelist,
_ReadDeviceFlag, _SetDeviceFlag,
psDeviceNode,
(void*)((uintptr_t)RGXKM_DEVICE_STATE_ZERO_FREELIST));
PVRSRVAppHintRegisterHandlersBOOL(APPHINT_ID_DisablePDumpPanic,
RGXQueryPdumpPanicDisable,
RGXSetPdumpPanicDisable,
psDeviceNode,
NULL);
}
信息页管理
超时信息初始化
static PVRSRV_ERROR InitialiseInfoPageTimeouts(PVRSRV_DATA *psPVRSRVData)
{
if (NULL == psPVRSRVData) {
return PVRSRV_ERROR_INVALID_PARAMS;
}
// 设置重试次数
psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_VALUE_RETRIES] = WAIT_TRY_COUNT;
// 设置超时时间(毫秒)
psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_VALUE_TIMEOUT_MS] =
((MAX_HW_TIME_US / 10000) + 1000);
/* 计算结果:
vp : 2000 + 1000 = 3000ms
emu : 2000 + 1000 = 3000ms
rgx_nohw : 50 + 1000 = 1050ms
plato : 30000 + 1000 = 31000ms (虚拟平台或模拟器)
50 + 1000 = 1050ms (其他)
*/
// 设置条件检查重试次数
psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_CONDITION_RETRIES] = 5;
// 设置条件检查超时(毫秒)
psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_CONDITION_TIMEOUT_MS] =
((MAX_HW_TIME_US / 10000) + 100);
/* 计算结果:
vp : 2000 + 100 = 2100ms
emu : 2000 + 100 = 2100ms
rgx_nohw : 50 + 100 = 150ms
plato : 30000 + 100 = 30100ms (虚拟平台或模拟器)
50 + 100 = 150ms (其他)
*/
// 设置任务队列重试次数
psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_TASK_QUEUE_RETRIES] = 10;
// 设置任务队列刷新超时(毫秒)
psPVRSRVData->pui32InfoPage[TIMEOUT_INFO_TASK_QUEUE_FLUSH_TIMEOUT_MS] =
MAX_HW_TIME_US / 1000U;
return PVRSRV_OK;
}
桥接信息填充
static PVRSRV_ERROR PopulateInfoPageBridges(PVRSRV_DATA *psPVRSRVData)
{
PVR_RETURN_IF_INVALID_PARAM(psPVRSRVData);
// 填充PVR桥接数量
psPVRSRVData->pui32InfoPage[BRIDGE_INFO_PVR_BRIDGES] = gui32PVRBridges;
#if defined(SUPPORT_RGX)
// 填充RGX桥接数量
psPVRSRVData->pui32InfoPage[BRIDGE_INFO_RGX_BRIDGES] = gui32RGXBridges;
#else
psPVRSRVData->pui32InfoPage[BRIDGE_INFO_RGX_BRIDGES] = 0;
#endif
return PVRSRV_OK;
}
设备状态管理
设备状态转换
void PVRSRVDeviceSetState(PVRSRV_DEVICE_NODE *psDeviceNode,
PVRSRV_DEVICE_STATE eNewDevState)
{
// 状态没有改变,直接返回
if (eNewDevState == psDeviceNode->eDevState) {
return;
}
switch (eNewDevState) {
case PVRSRV_DEVICE_STATE_PCI_ERROR:
// PCI错误是致命状态
PVR_DPF((PVR_DBG_ERROR, "%s: %s", __func__,
PVRSRVGetDebugDevStateString(eNewDevState)));
psDeviceNode->eDevState = eNewDevState;
#if defined(SUPPORT_PMR_DEFERRED_FREE)
// 释放所有僵尸PMR
PMRFreeZombies(psDeviceNode);
#endif
break;
case PVRSRV_DEVICE_STATE_CREATING:
case PVRSRV_DEVICE_STATE_CREATED:
case PVRSRV_DEVICE_STATE_ACTIVE:
case PVRSRV_DEVICE_STATE_FROZEN:
case PVRSRV_DEVICE_STATE_DEINIT:
case PVRSRV_DEVICE_STATE_DESTRUCTING:
case PVRSRV_DEVICE_STATE_BAD:
// PCI_ERROR是终止状态,重新加载驱动才能恢复
if (eNewDevState != PVRSRV_DEVICE_STATE_PCI_ERROR) {
psDeviceNode->eDevState = eNewDevState;
}
break;
case PVRSRV_DEVICE_STATE_UNDEFINED:
default:
PVR_DPF((PVR_DBG_ERROR, "%s: Unknown state (%d)",
__func__, eNewDevState));
break;
}
}
设备状态图
中断处理
LISR安装
PVRSRV_ERROR PVRSRVSystemInstallDeviceLISR(void *pvOSDevice,
IMG_UINT32 ui32IRQ,
const IMG_CHAR *pszName,
PFN_LISR pfnLISR,
void *pvData,
IMG_HANDLE *phLISRData)
{
PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
PVRSRV_DEVICE_NODE *psDeviceNode;
// 在设备列表中查找设备
OSWRLockAcquireRead(psPVRSRVData->hDeviceNodeListLock);
psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(
psPVRSRVData->psDeviceNodeList,
&PVRSRVSystemInstallDeviceLISR_Match_AnyVaCb,
pvOSDevice);
OSWRLockReleaseRead(psPVRSRVData->hDeviceNodeListLock);
if (!psDeviceNode) {
PVR_DPF((PVR_DBG_ERROR, "%s: device %p with irq %d is not present",
__func__, pvOSDevice, ui32IRQ));
return PVRSRV_ERROR_INVALID_DEVICE;
}
// 调用系统层安装LISR
return SysInstallDeviceLISR(psDeviceNode->psDevConfig->hSysData,
ui32IRQ, pszName, pfnLISR, pvData, phLISRData);
}
PVRSRV_ERROR PVRSRVSystemUninstallDeviceLISR(IMG_HANDLE hLISRData)
{
return SysUninstallDeviceLISR(hLISRData);
}
系统周期等待
void PVRSRVSystemWaitCycles(PVRSRV_DEVICE_CONFIG *psDevConfig,
IMG_UINT32 ui32Cycles)
{
IMG_UINT32 ui32Delayus = 1; // 默认延迟1微秒
// 获取设备频率并计算实际延迟
if (psDevConfig->pfnClockFreqGet != NULL) {
IMG_UINT32 ui32DeviceFreq;
ui32DeviceFreq = psDevConfig->pfnClockFreqGet(psDevConfig->hSysData);
// 延迟(微秒) = 周期数 * 1000000 / 频率
ui32Delayus = (ui32Cycles * 1000000) / ui32DeviceFreq;
if (ui32Delayus == 0) {
ui32Delayus = 1; // 最小延迟1微秒
}
}
OSWaitus(ui32Delayus);
}
驱动卸载流程
卸载序列图
卸载实现
void PVRSRVCommonDriverDeInit(void)
{
PVRSRV_ERROR eError = PVRSRV_OK;
IMG_BOOL bEnablePageFaultDebug = IMG_FALSE;
if (gpsPVRSRVData == NULL) {
PVR_DPF((PVR_DBG_ERROR, "%s: missing device-independent data",
__func__));
return;
}
// 检查页面故障调试是否启用
if (gpsPVRSRVData->pui32InfoPage != NULL) {
bEnablePageFaultDebug = GetInfoPageDebugFlagsKM() &
DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED;
}
// 1. 设置卸载标志
gpsPVRSRVData->bUnload = IMG_TRUE;
// 2. 停止HWPerf主机线程
#if defined(SUPPORT_RGX)
PVRSRVDestroyHWPerfHostThread();
if (gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock) {
OSLockDestroy(gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock);
gpsPVRSRVData->hHWPerfHostPeriodicThread_Lock = NULL;
}
#endif
// 3. 唤醒全局事件对象
if (gpsPVRSRVData->hGlobalEventObject) {
OSEventObjectSignal(gpsPVRSRVData->hGlobalEventObject);
}
// 4. 停止AutoVz看门狗线程
#if defined(SUPPORT_AUTOVZ)
if (gpsPVRSRVData->hAutoVzWatchdogThread) {
LOOP_UNTIL_TIMEOUT_US(OS_THREAD_DESTROY_TIMEOUT_US) {
if (gpsPVRSRVData->hAutoVzWatchdogEvObj) {
eError = OSEventObjectSignal(gpsPVRSRVData->hAutoVzWatchdogEvObj);
}
eError = OSThreadDestroy(gpsPVRSRVData->hAutoVzWatchdogThread);
if (PVRSRV_OK == eError) {
gpsPVRSRVData->hAutoVzWatchdogThread = NULL;
break;
}
OSWaitus(OS_THREAD_DESTROY_TIMEOUT_US/OS_THREAD_DESTROY_RETRY_COUNT);
} END_LOOP_UNTIL_TIMEOUT_US();
}
if (gpsPVRSRVData->hAutoVzWatchdogEvObj) {
eError = OSEventObjectDestroy(gpsPVRSRVData->hAutoVzWatchdogEvObj);
gpsPVRSRVData->hAutoVzWatchdogEvObj = NULL;
}
#endif
// 5. 停止设备看门狗线程
if (gpsPVRSRVData->hDevicesWatchdogThread) {
LOOP_UNTIL_TIMEOUT_US(OS_THREAD_DESTROY_TIMEOUT_US) {
if (gpsPVRSRVData->hDevicesWatchdogEvObj) {
eError = OSEventObjectSignal(gpsPVRSRVData->hDevicesWatchdogEvObj);
}
eError = OSThreadDestroy(gpsPVRSRVData->hDevicesWatchdogThread);
if (PVRSRV_OK == eError) {
gpsPVRSRVData->hDevicesWatchdogThread = NULL;
break;
}
OSWaitus(OS_THREAD_DESTROY_TIMEOUT_US/OS_THREAD_DESTROY_RETRY_COUNT);
} END_LOOP_UNTIL_TIMEOUT_US();
}
if (gpsPVRSRVData->hDevicesWatchdogEvObj) {
eError = OSEventObjectDestroy(gpsPVRSRVData->hDevicesWatchdogEvObj);
gpsPVRSRVData->hDevicesWatchdogEvObj = NULL;
}
// 6. 停止清理线程
if (gpsPVRSRVData->hCleanupThread) {
LOOP_UNTIL_TIMEOUT_US(OS_THREAD_DESTROY_TIMEOUT_US) {
if (gpsPVRSRVData->hCleanupEventObject) {
eError = OSEventObjectSignal(gpsPVRSRVData->hCleanupEventObject);
}
eError = OSThreadDestroy(gpsPVRSRVData->hCleanupThread);
if (PVRSRV_OK == eError) {
gpsPVRSRVData->hCleanupThread = NULL;
break;
}
OSWaitus(OS_THREAD_DESTROY_TIMEOUT_US/OS_THREAD_DESTROY_RETRY_COUNT);
} END_LOOP_UNTIL_TIMEOUT_US();
}
if (gpsPVRSRVData->hCleanupEventObject) {
eError = OSEventObjectDestroy(gpsPVRSRVData->hCleanupEventObject);
gpsPVRSRVData->hCleanupEventObject = NULL;
}
// 7. 清理HTB(Host Trace Buffer)
eError = HTBDeInit();
PVR_LOG_IF_ERROR(eError, "HTBDeInit");
// 8. 清理缓存操作框架
CacheOpDeInit2();
// 9. 销毁信息页
InfoPageDestroy(gpsPVRSRVData);
// 10. 关闭TL控制平面流
if (gpsPVRSRVData->hTLCtrlStream != NULL) {
TLStreamClose(gpsPVRSRVData->hTLCtrlStream);
}
// 11. 清理PDUMP
if ((g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0) {
PDUMPDEINIT();
}
// 12. 清理传输层
TLDeInit();
// 13. 销毁主机内存设备
HostMemDeviceDestroy(gpsPVRSRVData->psHostMemDeviceNode);
gpsPVRSRVData->psHostMemDeviceNode = NULL;
// 14. 清理句柄管理
eError = PVRSRVHandleDeInit();
PVR_LOG_IF_ERROR(eError, "PVRSRVHandleDeInit");
// 15. 销毁全局事件对象
if (gpsPVRSRVData->hGlobalEventObject) {
OSEventObjectDestroy(gpsPVRSRVData->hGlobalEventObject);
gpsPVRSRVData->hGlobalEventObject = NULL;
}
// 16. 清理命令完成系统
PVRSRVCmdCompleteDeinit();
// 17. 清理显示类支持
#if defined(PVRSRV_PHYSMEM_CPUMAP_HISTORY)
CPUMappingHistoryDeInit();
#endif
// 21. 清理设备内存历史
if (bEnablePageFaultDebug) {
DevicememHistoryDeInitKM();
}
// 22. 清理缓存操作
CacheOpDeInit();
// 23. 清理OS环境数据
OSDeInitEnvData();
// 24. 清理设备内存
(void)DevmemIntDeInit();
// 25. 清理服务器桥接
ServerBridgeDeInit();
// 26. 销毁HTB DI入口
HTB_DestroyDIEntry();
// 27. 第一阶段进程统计清理
#if defined(PVRSRV_ENABLE_PROCESS_STATS)
PVRSRVStatsDestroyDI();
#endif
// 28. 清理调试公共驱动
DebugCommonDeInitDriver();
// 29. 清理DI
DIDeInit();
// 30. 注销调试请求通知
if (gpsPVRSRVData->hThreadsDbgReqNotify) {
PVRSRVUnregisterDriverDbgRequestNotify(gpsPVRSRVData->hThreadsDbgReqNotify);
}
// 31. 注销驱动调试表
PVRSRVUnregisterDriverDbgTable();
// 32. 销毁设备节点列表锁
OSWRLockDestroy(gpsPVRSRVData->hDeviceNodeListLock);
// 33. 第二阶段进程统计清理
#if defined(PVRSRV_ENABLE_PROCESS_STATS)
PVRSRVStatsDestroy();
#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
RIDeInitKM();
#endif
#endif
// 34. 释放全局数据
OSFreeMemNoStats(gpsPVRSRVData);
gpsPVRSRVData = NULL;
}
19. 线程阻塞机制
19.1 阻塞检查
// 在pvrsrv.h中定义的宏
#define PVRSRVBlockIfFrozen(psDevNode) \
do { \
if (OSAtomicRead(&(psDevNode)->eFrozen) == _FROZEN) { \
PVRSRVBlockThread(psDevNode); \
} \
} while (0)
// 阻塞线程实现
static inline void PVRSRVBlockThread(PVRSRV_DEVICE_NODE *psDeviceNode)
{
IMG_HANDLE hOSEvent;
PVRSRV_ERROR eError;
// 增加冻结计数
OSAtomicIncrement(&psDeviceNode->iFreezeCount);
// 打开设备线程事件对象
eError = OSEventObjectOpen(psDeviceNode->hDeviceThreadEvObj, &hOSEvent);
if (eError != PVRSRV_OK) {
PVR_DPF((PVR_DBG_ERROR, "%s: Failed to open event object", __func__));
OSAtomicDecrement(&psDeviceNode->iFreezeCount);
return;
}
// 等待解冻信号
while (OSAtomicRead(&psDeviceNode->eFrozen) == _FROZEN) {
eError = OSEventObjectWaitKernel(hOSEvent,
EVENT_OBJECT_TIMEOUT_MS * 1000);
if (eError != PVRSRV_OK && eError != PVRSRV_ERROR_TIMEOUT) {
PVR_DPF((PVR_DBG_WARNING, "%s: Wait failed with error %d",
__func__, eError));
break;
}
}
// 关闭事件对象
OSEventObjectClose(hOSEvent);
// 减少冻结计数
OSAtomicDecrement(&psDeviceNode->iFreezeCount);
}
代码框架总结
模块层次结构
pvrsrv.c (核心服务层)
├── 初始化管理
│ ├── PVRSRVCommonDriverInit() - 驱动初始化
│ ├── PVRSRVCommonDeviceCreate() - 设备创建
│ ├── PVRSRVCommonDeviceInitialise()- 设备初始化
│ └── PVRSRVDeviceFinalise() - 设备最终化
│
├── 设备管理
│ ├── PVRSRVGetDeviceInstance() - 获取设备实例
│ ├── PVRSRVDeviceSetState() - 设置设备状态
│ ├── PVRSRVDeviceFreeze() - 冻结设备
│ └── PVRSRVDeviceThaw() - 解冻设备
│
├── 线程管理
│ ├── CleanupThread() - 延迟清理线程
│ ├── DevicesWatchdogThread() - 设备看门狗线程
│ ├── HWPerfPeriodicHostEventsThread() - HWPerf主机线程
│ └── AutoVzWatchdogThread() - AutoVz看门狗线程
│
├── 清理机制
│ ├── PVRSRVCleanupThreadAddWork() - 添加清理工作
│ ├── _CleanupThreadProcessWorkList()- 处理清理列表
│ └── PVRSRVCleanupThreadWaitForDevice() - 等待设备清理
│
├── 电源管理
│ ├── PVRSRVPollForValueKM() - 轮询等待
│ ├── PVRSRVWaitForValueKM() - 事件等待
│ └── PVRSRVWaitForConditionKM() - 条件等待
│
├── 系统查询
│ ├── PVRSRVSystemHasCacheSnooping()- 查询缓存窥探
│ ├── PVRSRVSystemSnoopingIsEmulated() - 查询模拟窥探
│ └── PVRSRVFindPhysHeapConfig() - 查找物理堆配置
│
├── 中断处理
│ ├── PVRSRVSystemInstallDeviceLISR() - 安装LISR
│ └── PVRSRVSystemUninstallDeviceLISR() - 卸载LISR
│
├── 虚拟化支持
│ ├── _InitDefaultVzDriverMode() - 初始化虚拟化模式
│ ├── PVRSRVGetVzModeByDevNum() - 获取虚拟化模式
│ └── PvzConnection相关函数 - 虚拟化连接管理
│
├── 调试支持
│ ├── _SysDebugRequestNotify() - 系统调试通知
│ ├── CleanupThreadDumpInfo() - 清理线程信息转储
│ └── _CleanupThreadWorkListDump() - 工作列表转储
│
└── 清理与销毁
├── PVRSRVCommonDeviceDestroy() - 设备销毁
└── PVRSRVCommonDriverDeInit() - 驱动清理
关键数据流图
线程交互图
性能优化要点
延迟清理机制的优势
- 非阻塞操作:资源释放请求立即返回,不阻塞调用线程
- 批量处理:可以批量处理多个清理请求,提高效率
- 错误恢复:清理失败可以重试,不影响主流程
- 资源平衡:在系统空闲时执行清理,减少对性能的影响
看门狗机制的优势
- 状态监控:定期检查设备健康状态,及时发现问题
- 自适应超时:根据设备电源状态调整检查频率
- 故障恢复:支持固件恢复机制,提高系统可靠性
- 资源节省:设备下电时降低检查频率
冻结/解冻机制的应用
- LBIST测试:在内建自测试期间冻结设备
- 固件更新:在更新固件时冻结设备操作
- 调试支持:在调试时冻结设备状态
- 电源管理:配合电源状态转换
关键宏定义
// 清理类型统计相关
#define CLEANUP_QUEUE_TOTAL_DPF "QUEUED: %1.5d "
#define CLEANUP_TYPE_ITEM_DPF "%s: %1.5d "
#define CLEANUP_TYPE_ITEM_DPF_MAX_SIZE 20
// 冻结状态定义
#define _FROZEN 1
#define _NOT_FROZEN 0
// 虚拟化模式字符串
static const IMG_CHAR *const asModeStrings[] = {
"native", // 原生模式
"host", // 主机模式
"guest", // 客户模式
"default" // 默认模式
};
// 初始化标志
#define INIT_DATA_ENABLE_PDUMPINIT 0x1U
// 虚拟化模式缓冲区大小
#define PVRVZMODE_STR_SIZE_MAX 10U
#define PVRVZMODE_BUFFER_SIZE (((PVRSRV_MAX_DEVICES)*(PVRVZMODE_STR_SIZE_MAX))+1)
总结
代码特点
- 模块化设计:功能划分清晰,各模块职责明确
- 异步处理:延迟清理、后台监控等异步机制
- 错误处理:完善的错误检测和恢复机制
- 状态管理:精细的设备状态转换控制
- 并发控制:使用锁、原子操作等保证线程安全
- 资源管理:严格的资源生命周期管理
关键技术
- 延迟清理:非阻塞资源释放机制
- 看门狗:自适应的设备健康监控
- 冻结机制:支持特殊操作的设备阻塞
- 虚拟化支持:多种驱动模式(native/host/guest)
- 电源管理:精细的电源状态控制
- 调试支持:丰富的调试信息和转储机制
代码质量
- 可维护性:代码结构清晰,注释详细
- 可扩展性:良好的抽象和接口设计
- 可靠性:全面的错误处理和恢复
- 性能:优化的异步处理和资源管理
- 可移植性:通过抽象层支持多平台
这个文件是PowerVR驱动的核心,协调了设备管理、内存管理、电源管理、同步等各个子系统,是理解整个驱动架构的关键。
JINHU