1 /*************************************************************************/ /*!
3 @Title core services functions
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description Main APIs for core services functions
6 @License Dual MIT/GPLv2
8 The contents of this file are subject to the MIT license as set out below.
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
20 Alternatively, the contents of this file may be used under the terms of
21 the GNU General Public License Version 2 ("GPL") in which case the provisions
22 of GPL are applicable instead of those above.
24 If you wish to allow use of your version of this file only under the terms of
25 GPL, and not to allow others to use your version of this file under the terms
26 of the MIT license, indicate your decision by deleting the provisions above
27 and replace them with the notice and other provisions required by GPL as set
28 out in the file called "GPL-COPYING" included in this distribution. If you do
29 not delete the provisions above, a recipient may use your version of this file
30 under the terms of either the MIT license or GPL.
32 This License is also included in this distribution in the file called
35 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
36 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
37 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
39 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
40 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 */ /**************************************************************************/
46 #include "connection_server.h"
51 #include "dc_server.h"
53 #include "pvrsrv_device.h"
54 #include "pvr_debug.h"
56 #include "sync_server.h"
57 #include "devicemem.h"
59 #include "pvrversion.h"
63 #include "syscommon.h"
65 #include "physmem_lma.h"
66 #include "physmem_osmem.h"
70 #if defined (SUPPORT_RGX)
74 #include "debug_request_ids.h"
77 #if defined(PVR_RI_DEBUG)
78 #include "ri_server.h"
81 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
82 #include "process_stats.h"
84 /*! Wait 100ms before retrying deferred clean-up again */
85 #define CLEANUP_THREAD_WAIT_RETRY_TIMEOUT 0x00000064
87 /*! Wait 8hrs when no deferred clean-up required. Allows a poll several times
88 * a day to check for any missed clean-up. */
89 #define CLEANUP_THREAD_WAIT_SLEEP_TIMEOUT 0x01B77400
92 typedef struct DEBUG_REQUEST_ENTRY_TAG
94 IMG_UINT32 ui32RequesterID;
95 DLLIST_NODE sListHead;
96 } DEBUG_REQUEST_ENTRY;
98 typedef struct DEBUG_REQUEST_TABLE_TAG
100 IMG_UINT32 ui32RequestCount;
101 DEBUG_REQUEST_ENTRY asEntry[1];
102 }DEBUG_REQUEST_TABLE;
104 static PVRSRV_DATA *gpsPVRSRVData = IMG_NULL;
105 static IMG_HANDLE g_hDbgSysNotify;
107 static PVRSRV_SYSTEM_CONFIG *gpsSysConfig = IMG_NULL;
109 typedef PVRSRV_ERROR (*PFN_REGISTER_DEVICE)(PVRSRV_DEVICE_NODE *psDeviceNode);
110 typedef PVRSRV_ERROR (*PFN_UNREGISTER_DEVICE)(PVRSRV_DEVICE_NODE *psDeviceNode);
112 static PFN_REGISTER_DEVICE sRegisterDevice[PVRSRV_DEVICE_TYPE_LAST + 1];
113 static PFN_UNREGISTER_DEVICE sUnregisterDevice[PVRSRV_DEVICE_TYPE_LAST + 1];
115 static PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PVRSRV_DEVICE_CONFIG *psDevConfig);
116 static PVRSRV_ERROR IMG_CALLCONV PVRSRVUnregisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
118 static PVRSRV_ERROR PVRSRVRegisterDbgTable(IMG_UINT32 *paui32Table, IMG_UINT32 ui32Length, IMG_PVOID *phTable);
119 static IMG_VOID PVRSRVUnregisterDbgTable(IMG_PVOID hTable);
121 static IMG_VOID _SysDebugRequestNotify(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, IMG_UINT32 ui32VerbLevel);
123 IMG_UINT32 g_ui32InitFlags;
125 /* mark which parts of Services were initialised */
126 #define INIT_DATA_ENABLE_PDUMPINIT 0x1U
127 #define INIT_GLOBAL_RESMAN 0x2U
129 /* Head of the list of callbacks called when Cmd complete happens */
130 static DLLIST_NODE sCmdCompNotifyHead;
131 static POSWR_LOCK hNotifyLock = IMG_NULL;
133 /* Debug request table and lock */
134 static POSWR_LOCK g_hDbgNotifyLock = IMG_NULL;
135 static DEBUG_REQUEST_TABLE *g_psDebugTable;
137 static IMG_PVOID g_hDebugTable = IMG_NULL;
139 static IMG_UINT32 g_aui32DebugOrderTable[] = {
143 DEBUG_REQUEST_SERVERSYNC,
144 DEBUG_REQUEST_ANDROIDSYNC
147 DUMPDEBUG_PRINTF_FUNC *g_pfnDumpDebugPrintf = IMG_NULL;
149 ******************************************************************************
151 @Function AllocateDeviceID
155 allocates a device id from the pool of valid ids
157 @input psPVRSRVData : Services private data
159 @input pui32DevID : device id to return
163 ******************************************************************************/
164 static PVRSRV_ERROR AllocateDeviceID(PVRSRV_DATA *psPVRSRVData, IMG_UINT32 *pui32DevID)
166 SYS_DEVICE_ID* psDeviceWalker;
167 SYS_DEVICE_ID* psDeviceEnd;
169 psDeviceWalker = &psPVRSRVData->sDeviceID[0];
170 psDeviceEnd = psDeviceWalker + SYS_DEVICE_COUNT;
173 while (psDeviceWalker < psDeviceEnd)
175 if (!psDeviceWalker->bInUse)
177 psDeviceWalker->bInUse = IMG_TRUE;
178 *pui32DevID = psDeviceWalker->uiID;
185 PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!"));
187 /* Should never get here: sDeviceID[] may have been setup too small */
188 PVR_ASSERT(psDeviceWalker < psDeviceEnd);
190 return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVAILABLE;
195 ******************************************************************************
197 @Function FreeDeviceID
201 frees a device id from the pool of valid ids
203 @input psPVRSRVData : Services private data
205 @input ui32DevID : device id to free
209 ******************************************************************************/
210 static PVRSRV_ERROR FreeDeviceID(PVRSRV_DATA *psPVRSRVData, IMG_UINT32 ui32DevID)
212 SYS_DEVICE_ID* psDeviceWalker;
213 SYS_DEVICE_ID* psDeviceEnd;
215 psDeviceWalker = &psPVRSRVData->sDeviceID[0];
216 psDeviceEnd = psDeviceWalker + SYS_DEVICE_COUNT;
218 /* find the ID to free */
219 while (psDeviceWalker < psDeviceEnd)
221 /* if matching id and in use, free */
223 (psDeviceWalker->uiID == ui32DevID) &&
224 (psDeviceWalker->bInUse)
227 psDeviceWalker->bInUse = IMG_FALSE;
233 PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!"));
235 /* should never get here */
236 PVR_ASSERT(psDeviceWalker < psDeviceEnd);
238 return PVRSRV_ERROR_INVALID_DEVICEID;
243 ******************************************************************************
244 @Function PVRSRVEnumerateDevicesKM_ForEachVaCb
248 Enumerates the device node (if is of the same class as given).
250 @Input psDeviceNode - The device node to be enumerated
251 va - variable arguments list, with:
252 pui32DevCount - The device count pointer (to be increased)
253 ppeDeviceType - The pointer to the device type pointer (to be updated and increased)
254 ppeDeviceClass - The pointer to the device classes pointer (to be updated and increased)
255 ppui32DeviceIndex - The pointer to the device indexes pointer (to be updated and increased)
256 ******************************************************************************/
257 static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
259 IMG_UINT *pui32DevCount;
260 PVRSRV_DEVICE_TYPE **ppeDeviceType;
261 PVRSRV_DEVICE_CLASS **ppeDeviceClass;
262 IMG_UINT32 **ppui32DeviceIndex;
264 pui32DevCount = va_arg(va, IMG_UINT*);
265 ppeDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE**);
266 ppeDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS**);
267 ppui32DeviceIndex = va_arg(va, IMG_UINT32**);
269 if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT)
271 **ppeDeviceType = psDeviceNode->sDevId.eDeviceType;
272 **ppeDeviceClass = psDeviceNode->sDevId.eDeviceClass;
273 **ppui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
277 (*ppui32DeviceIndex)++;
286 ******************************************************************************
288 @Function PVRSRVEnumerateDevicesKM
291 This function will enumerate all the devices supported by the
292 PowerVR services within the target system.
293 The function returns a list of the device ID structures stored either in
294 the services or constructed in the user mode glue component in certain
295 environments. The number of devices in the list is also returned.
297 In a binary layered component which does not support dynamic runtime selection,
298 the glue code should compile to return the supported devices statically,
299 e.g. multiple instances of the same device if multiple devices are supported,
300 or the target combination of Rogue and display device.
302 In the case of an environment (for instance) where one Rogue may connect to two
303 display devices this code would enumerate all three devices and even
304 non-dynamic Rogue selection code should retain the facility to parse the list
305 to find the index of the Rogue device
307 @output pui32NumDevices : On success, contains the number of devices present
310 @output peDeviceType : Pointer to called supplied buffer to receive the
311 list of PVRSRV_DEVICE_TYPE
313 @output peDeviceClass : Pointer to called supplied buffer to receive the
314 list of PVRSRV_DEVICE_CLASS
316 @output pui32DeviceIndex: Pointer to called supplied buffer to receive the
317 list of device indexes
319 @return PVRSRV_ERROR :
321 ******************************************************************************/
323 PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
324 PVRSRV_DEVICE_TYPE *peDeviceType,
325 PVRSRV_DEVICE_CLASS *peDeviceClass,
326 IMG_UINT32 *pui32DeviceIndex)
328 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
331 if (!pui32NumDevices || !peDeviceType || !peDeviceClass || !pui32DeviceIndex)
333 PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params"));
334 return PVRSRV_ERROR_INVALID_PARAMS;
338 setup input buffer to be `empty'
340 for (i=0; i<PVRSRV_MAX_DEVICES; i++)
342 peDeviceType[i] = PVRSRV_DEVICE_TYPE_UNKNOWN;
345 /* and zero device count */
346 *pui32NumDevices = 0;
349 Search through the device list for services managed devices
350 return id info for each device and the number of devices
353 List_PVRSRV_DEVICE_NODE_ForEach_va(psPVRSRVData->psDeviceNodeList,
354 &PVRSRVEnumerateDevicesKM_ForEachVaCb,
363 // #define CLEANUP_DPFL PVR_DBG_WARNING
364 #define CLEANUP_DPFL PVR_DBG_MESSAGE
366 static IMG_VOID CleanupThread(IMG_PVOID pvData)
368 PVRSRV_DATA *psPVRSRVData = pvData;
369 IMG_BOOL bRetryCleanup = IMG_FALSE;
372 IMG_UINT64 ui64TimesliceLimit;
374 /* Store the process id (pid) of the clean-up thread */
375 psPVRSRVData->cleanupThreadPid = OSGetCurrentProcessIDKM();
377 PVR_DPF((CLEANUP_DPFL, "CleanupThread: thread starting... "));
379 /* Open an event on the clean up event object so we can listen on it,
380 * abort the clean up thread and driver if this fails.
382 eRc = OSEventObjectOpen(psPVRSRVData->hCleanupEventObject, &hOSEvent);
383 PVR_ASSERT(eRc == PVRSRV_OK);
385 /* While the driver is in a good state and is not being unloaded
386 * try to free any deferred items when RESMAN signals
388 while ((psPVRSRVData->eServicesState == PVRSRV_SERVICES_STATE_OK) &&
389 (!psPVRSRVData->bUnload))
391 /* Wait until RESMAN signals for deferred clean up OR wait for a
392 * short period if the previous deferred clean up was not able
393 * to release all the resources before trying again.
394 * Bridge lock re-acquired on our behalf before the wait call returns.
396 eRc = OSEventObjectWaitTimeout(hOSEvent, (bRetryCleanup) ?
397 CLEANUP_THREAD_WAIT_RETRY_TIMEOUT :
398 CLEANUP_THREAD_WAIT_SLEEP_TIMEOUT);
399 if (eRc == PVRSRV_ERROR_TIMEOUT)
401 PVR_DPF((CLEANUP_DPFL, "CleanupThread: wait timeout"));
403 else if (eRc == PVRSRV_OK)
405 PVR_DPF((CLEANUP_DPFL, "CleanupThread: wait OK, signal received"));
409 PVR_DPF((PVR_DBG_ERROR, "CleanupThread: wait error %d", eRc));
412 /* Acquire the bridge lock to protect the flush of the deferred contexts
413 * and to guarantee the consistency of the deferred contexts list.
414 * In order to avoid to block the system during the cleanup the lock is
415 * released periodically every time a specific time expires.
417 OSAcquireBridgeLock();
419 /* Estimate the time limit as soon as we acquire the global lock */
420 ui64TimesliceLimit = OSClockns64() + RESMAN_DEFERRED_CLEANUP_TIMESLICE_NS;
422 /* Attempt to clean up all deferred contexts that may exist. If
423 * resources still need cleanup on exit bRetryCleanup set to true.
425 bRetryCleanup = PVRSRVResManFlushDeferContext(
426 psPVRSRVData->hResManDeferContext,
429 /* Release the bridge lock after the cleanup of the defer context */
430 OSReleaseBridgeLock();
433 eRc = OSEventObjectClose(hOSEvent);
434 PVR_LOG_IF_ERROR(eRc, "OSEventObjectClose");
436 PVR_DPF((CLEANUP_DPFL, "CleanupThread: thread ending... "));
440 static IMG_VOID DevicesWatchdogThread(IMG_PVOID pvData)
442 PVRSRV_DATA *psPVRSRVData = pvData;
443 PVRSRV_DEVICE_HEALTH_STATUS ePreviousHealthStatus = PVRSRV_DEVICE_HEALTH_STATUS_OK;
446 IMG_UINT32 ui32Timeout = DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT;
447 PVRSRV_DEV_POWER_STATE ePowerState;
449 PVR_DPF((PVR_DBG_MESSAGE, "DevicesWatchdogThread: Power off sleep time: %d.",
450 DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT));
452 /* Open an event on the devices watchdog event object so we can listen on it
453 and abort the devices watchdog thread. */
454 eError = OSEventObjectOpen(psPVRSRVData->hDevicesWatchdogEvObj, &hOSEvent);
455 PVR_LOGRN_IF_ERROR(eError, "OSEventObjectOpen");
457 /* Loop continuously checking the device status every few seconds. */
458 while (!psPVRSRVData->bUnload)
461 IMG_BOOL bPwrIsOn = IMG_FALSE;
463 /* Wait time between polls (done at the start of the loop to allow devices
464 to initialise) or for the event signal (shutdown or power on). */
465 eError = OSEventObjectWaitTimeout(hOSEvent, ui32Timeout);
467 #ifdef PVR_TESTING_UTILS
468 psPVRSRVData->ui32DevicesWdWakeupCounter++;
470 if (eError == PVRSRV_OK)
472 if (psPVRSRVData->bUnload)
474 PVR_DPF((PVR_DBG_MESSAGE, "DevicesWatchdogThread: Shutdown event received."));
479 PVR_DPF((PVR_DBG_MESSAGE, "DevicesWatchdogThread: Power state change event received."));
482 else if (eError != PVRSRV_ERROR_TIMEOUT)
484 /* If timeout do nothing otherwise print warning message. */
485 PVR_DPF((PVR_DBG_ERROR, "DevicesWatchdogThread: "
486 "Error (%d) when waiting for event!", eError));
489 eError = PVRSRVPowerLock();
490 if (eError == PVRSRV_ERROR_RETRY)
492 /* power lock cannot be acquired at this time (sys power is off) */
493 ui32Timeout = psPVRSRVData->ui32DevicesWatchdogTimeout = DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT;
495 else if (eError != PVRSRV_OK)
497 /* any other error is unexpected */
498 PVR_DPF((PVR_DBG_ERROR,"DevicesWatchdogThread: Failed to acquire power lock (%s)", PVRSRVGetErrorStringKM(eError)));
502 /* Check if at least one of the devices is on. */
503 for (i = 0; i < psPVRSRVData->ui32RegisteredDevices && !bPwrIsOn; i++)
505 if (PVRSRVGetDevicePowerState(i, &ePowerState) == PVRSRV_OK)
507 bPwrIsOn = ePowerState == PVRSRV_DEV_POWER_STATE_ON;
512 if (bPwrIsOn || psPVRSRVData->ui32DevicesWatchdogPwrTrans)
514 psPVRSRVData->ui32DevicesWatchdogPwrTrans = 0;
515 ui32Timeout = psPVRSRVData->ui32DevicesWatchdogTimeout = DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT;
519 ui32Timeout = psPVRSRVData->ui32DevicesWatchdogTimeout = DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT;
525 for (i = 0; i < psPVRSRVData->ui32RegisteredDevices; i++)
527 PVRSRV_DEVICE_NODE* psDeviceNode = psPVRSRVData->apsRegisteredDevNodes[i];
528 PVRSRV_RGXDEV_INFO* psDevInfo = (PVRSRV_RGXDEV_INFO*) psDeviceNode->pvDevice;
530 if (psDeviceNode->pfnUpdateHealthStatus != IMG_NULL)
532 eError = psDeviceNode->pfnUpdateHealthStatus(psDeviceNode, IMG_TRUE);
533 if (eError != PVRSRV_OK)
535 PVR_DPF((PVR_DBG_WARNING, "DevicesWatchdogThread: "
536 "Could not check for fatal error (%d)!",
541 if (psDeviceNode->eHealthStatus != PVRSRV_DEVICE_HEALTH_STATUS_OK)
543 if (psDeviceNode->eHealthStatus != ePreviousHealthStatus)
545 if (!(psDevInfo->ui32DeviceFlags & RGXKM_DEVICE_STATE_DISABLE_DW_LOGGING_EN))
547 PVR_DPF((PVR_DBG_ERROR, "DevicesWatchdogThread: Device not responding!!!"));
548 PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, IMG_NULL);
552 ePreviousHealthStatus = psDeviceNode->eHealthStatus;
554 /* Attempt to service the HWPerf buffer to regularly transport
555 * idle / periodic packets to host buffer. */
556 if (psDeviceNode->pfnServiceHWPerf != IMG_NULL)
558 eError = psDeviceNode->pfnServiceHWPerf(psDeviceNode);
559 if (eError != PVRSRV_OK)
561 PVR_DPF((PVR_DBG_WARNING, "DevicesWatchdogThread: "
562 "Error occurred when servicing HWPerf buffer (%d)",
569 eError = OSEventObjectClose(hOSEvent);
570 PVR_LOG_IF_ERROR(eError, "OSEventObjectClose");
574 PVRSRV_DATA *PVRSRVGetPVRSRVData()
576 return gpsPVRSRVData;
580 PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(IMG_VOID)
583 PVRSRV_SYSTEM_CONFIG *psSysConfig;
586 #if defined (SUPPORT_RGX)
588 sRegisterDevice[PVRSRV_DEVICE_TYPE_RGX] = RGXRegisterDevice;
591 SET_LOG2_PAGESIZE(OSGetPageShift());
593 eError = PhysHeapInit();
594 if (eError != PVRSRV_OK)
599 /* Get the system config */
600 eError = SysCreateConfigData(&psSysConfig);
601 if (eError != PVRSRV_OK)
606 /* Save to global pointer for later */
607 gpsSysConfig = psSysConfig;
610 * Allocate the device-independent data
612 gpsPVRSRVData = OSAllocMem(sizeof(*gpsPVRSRVData));
613 if (gpsPVRSRVData == IMG_NULL)
615 return PVRSRV_ERROR_OUT_OF_MEMORY;
617 OSMemSet(gpsPVRSRVData, 0, sizeof(*gpsPVRSRVData));
618 gpsPVRSRVData->ui32NumDevices = psSysConfig->uiDeviceCount;
620 for (i=0;i<SYS_DEVICE_COUNT;i++)
622 gpsPVRSRVData->sDeviceID[i].uiID = i;
623 gpsPVRSRVData->sDeviceID[i].bInUse = IMG_FALSE;
627 * Register the physical memory heaps
629 PVR_ASSERT(psSysConfig->ui32PhysHeapCount <= SYS_PHYS_HEAP_COUNT);
630 for (i=0;i<psSysConfig->ui32PhysHeapCount;i++)
632 eError = PhysHeapRegister(&psSysConfig->pasPhysHeaps[i],
633 &gpsPVRSRVData->apsRegisteredPhysHeaps[i]);
634 if (eError != PVRSRV_OK)
638 gpsPVRSRVData->ui32RegisteredPhysHeaps++;
641 /* Init any OS specific's */
642 eError = OSInitEnvData();
643 if (eError != PVRSRV_OK)
648 /* Initialise Resource Manager */
649 eError = ResManInit();
650 if (eError != PVRSRV_OK)
655 eError = PVRSRVConnectionInit();
656 if(eError != PVRSRV_OK)
661 #if defined(PVR_RI_DEBUG)
666 if (eError != PVRSRV_OK)
671 #if !defined(UNDER_WDDM) && defined(SUPPORT_DISPLAY_CLASS)
673 if (eError != PVRSRV_OK)
679 /* Initialise handles */
680 eError = PVRSRVHandleInit();
681 if(eError != PVRSRV_OK)
686 /* Initialise Power Manager Lock */
687 eError = OSLockCreate(&gpsPVRSRVData->hPowerLock, LOCK_TYPE_PASSIVE);
688 if (eError != PVRSRV_OK)
693 /* Initialise system power state */
694 gpsPVRSRVData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_ON;
695 gpsPVRSRVData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
697 /* Initialise overall system state */
698 gpsPVRSRVData->eServicesState = PVRSRV_SERVICES_STATE_OK;
700 /* Create an event object */
701 eError = OSEventObjectCreate("PVRSRV_GLOBAL_EVENTOBJECT", &gpsPVRSRVData->hGlobalEventObject);
702 if (eError != PVRSRV_OK)
706 gpsPVRSRVData->ui32GEOConsecutiveTimeouts = 0;
708 /* initialise list of command complete notifiers */
709 dllist_init(&sCmdCompNotifyHead);
711 /* Create a lock of the list notifiers */
712 eError = OSWRLockCreate(&hNotifyLock);
713 if (eError != PVRSRV_OK)
718 /* Create a lock of the debug notifiers */
719 eError = OSWRLockCreate(&g_hDbgNotifyLock);
720 if (eError != PVRSRV_OK)
725 eError = PVRSRVRegisterDbgTable(g_aui32DebugOrderTable,
726 sizeof(g_aui32DebugOrderTable)/sizeof(g_aui32DebugOrderTable[0]),
728 if (eError != PVRSRV_OK)
733 PVRSRVRegisterDbgRequestNotify(&g_hDbgSysNotify, &_SysDebugRequestNotify, DEBUG_REQUEST_SYS, gpsPVRSRVData);
735 eError = ServerSyncInit();
736 if (eError != PVRSRV_OK)
741 /* Initialise pdump */
742 eError = PDUMPINIT();
743 if(eError != PVRSRV_OK)
748 g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT;
750 /* Register all the system devices */
751 for (i=0;i<psSysConfig->uiDeviceCount;i++)
753 if (PVRSRVRegisterDevice(&psSysConfig->pasDevices[i]) != PVRSRV_OK)
759 /* Initialise the Transport Layer.
760 * Need to remember the RGX device node for use in the Transport Layer
761 * when allocating stream buffers that are shared with clients.
762 * Note however when the device is an LMA device our buffers will not
763 * be in host memory but card memory.
765 if (gpsPVRSRVData->apsRegisteredDevNodes[gpsPVRSRVData->ui32RegisteredDevices-1]->psDevConfig->eDeviceType == PVRSRV_DEVICE_TYPE_RGX)
767 eError = TLInit(gpsPVRSRVData->apsRegisteredDevNodes[gpsPVRSRVData->ui32RegisteredDevices-1]);
768 PVR_LOGG_IF_ERROR(eError, "TLInit", Error);
772 /* Create the clean up event object */
773 eError = OSEventObjectCreate("PVRSRV_CLEANUP_EVENTOBJECT", &gpsPVRSRVData->hCleanupEventObject);
774 PVR_LOGG_IF_ERROR(eError, "OSEventObjectCreate", Error);
776 eError = PVRSRVResManCreateDeferContext(gpsPVRSRVData->hCleanupEventObject,
777 &gpsPVRSRVData->hResManDeferContext);
778 PVR_LOGG_IF_ERROR(eError, "PVRSRVResManCreateDeferContext", Error);
780 g_ui32InitFlags |= INIT_GLOBAL_RESMAN;
782 /* Create a thread which is used to do the deferred cleanup running with the
784 eError = OSThreadCreatePriority(&gpsPVRSRVData->hCleanupThread,
790 if (eError != PVRSRV_OK)
792 PVR_DPF((PVR_DBG_ERROR,"PVRSRVInit: Failed to create deferred cleanup thread"));
796 /* Create the devices watchdog event object */
797 eError = OSEventObjectCreate("PVRSRV_DEVICESWATCHDOG_EVENTOBJECT", &gpsPVRSRVData->hDevicesWatchdogEvObj);
798 PVR_LOGG_IF_ERROR(eError, "OSEventObjectCreate", Error);
800 /* Create a thread which is used to detect fatal errors */
801 eError = OSThreadCreate(&gpsPVRSRVData->hDevicesWatchdogThread,
802 "pvr_devices_wd_thread",
803 DevicesWatchdogThread,
805 if (eError != PVRSRV_OK)
807 PVR_DPF((PVR_DBG_ERROR,"PVRSRVInit: Failed to create devices watchdog thread"));
811 #if defined(PVR_TESTING_UTILS)
823 IMG_VOID IMG_CALLCONV PVRSRVDeInit(IMG_VOID)
825 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
829 if (gpsPVRSRVData == IMG_NULL)
831 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit failed - invalid gpsPVRSRVData"));
835 #if defined(PVR_TESTING_UTILS)
839 #if defined (SUPPORT_RGX)
840 sUnregisterDevice[PVRSRV_DEVICE_TYPE_RGX] = DevDeInitRGX;
843 psPVRSRVData->bUnload = IMG_TRUE;
844 if (psPVRSRVData->hGlobalEventObject)
846 OSEventObjectSignal(psPVRSRVData->hGlobalEventObject);
849 /* Stop and cleanup the devices watchdog thread */
850 if (psPVRSRVData->hDevicesWatchdogThread)
852 if (psPVRSRVData->hDevicesWatchdogEvObj)
854 eError = OSEventObjectSignal(psPVRSRVData->hDevicesWatchdogEvObj);
855 PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
857 eError = OSThreadDestroy(gpsPVRSRVData->hDevicesWatchdogThread);
858 gpsPVRSRVData->hDevicesWatchdogThread = IMG_NULL;
859 PVR_LOG_IF_ERROR(eError, "OSThreadDestroy");
862 if (gpsPVRSRVData->hDevicesWatchdogEvObj)
864 eError = OSEventObjectDestroy(gpsPVRSRVData->hDevicesWatchdogEvObj);
865 gpsPVRSRVData->hDevicesWatchdogEvObj = IMG_NULL;
866 PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy");
869 /* Stop and cleanup the deferred clean up thread, event object and
870 * deferred context list.
872 if (psPVRSRVData->hCleanupThread)
874 if (psPVRSRVData->hCleanupEventObject)
876 eError = OSEventObjectSignal(psPVRSRVData->hCleanupEventObject);
877 PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
879 eError = OSThreadDestroy(gpsPVRSRVData->hCleanupThread);
880 gpsPVRSRVData->hCleanupThread = IMG_NULL;
881 PVR_LOG_IF_ERROR(eError, "OSThreadDestroy");
884 if (gpsPVRSRVData->hCleanupEventObject)
886 eError = OSEventObjectDestroy(gpsPVRSRVData->hCleanupEventObject);
887 gpsPVRSRVData->hCleanupEventObject = IMG_NULL;
888 PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy");
891 if (g_ui32InitFlags & INIT_GLOBAL_RESMAN)
893 PVRSRVResManDestroyDeferContext(gpsPVRSRVData->hResManDeferContext);
896 /* Unregister all the system devices */
897 for (i=0;i<psPVRSRVData->ui32RegisteredDevices;i++)
899 PVRSRV_DEVICE_NODE *psDeviceNode = psPVRSRVData->apsRegisteredDevNodes[i];
901 /* set device state */
902 psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_DEINIT;
904 /* Counter part to what gets done in PVRSRVFinaliseSystem */
905 if (psDeviceNode->hSyncPrimContext != IMG_NULL)
907 if (psDeviceNode->psSyncPrim != IMG_NULL)
909 /* Free general pupose sync primitive */
910 SyncPrimFree(psDeviceNode->psSyncPrim);
911 psDeviceNode->psSyncPrim = IMG_NULL;
913 if (psDeviceNode->psSyncPrimPreKick != IMG_NULL)
915 /* Free PreKick sync primitive */
916 SyncPrimFree(psDeviceNode->psSyncPrimPreKick);
917 psDeviceNode->psSyncPrimPreKick = IMG_NULL;
920 SyncPrimContextDestroy(psDeviceNode->hSyncPrimContext);
921 psDeviceNode->hSyncPrimContext = IMG_NULL;
924 PVRSRVUnregisterDevice(psDeviceNode);
925 psPVRSRVData->apsRegisteredDevNodes[i] = IMG_NULL;
927 SysDestroyConfigData(gpsSysConfig);
929 /* Clean up Transport Layer resources that remain.
930 * Done after RGX node clean up as HWPerf stream is destroyed during
939 PVRSRVUnregisterDbgRequestNotify(g_hDbgSysNotify);
944 PVRSRVUnregisterDbgTable(g_hDebugTable);
947 if (g_hDbgNotifyLock)
949 OSWRLockDestroy(g_hDbgNotifyLock);
954 OSWRLockDestroy(hNotifyLock);
957 /* deinitialise pdump */
958 if ((g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0)
963 /* destroy event object */
964 if (gpsPVRSRVData->hGlobalEventObject)
966 OSEventObjectDestroy(gpsPVRSRVData->hGlobalEventObject);
967 gpsPVRSRVData->hGlobalEventObject = IMG_NULL;
970 /* Check there is no notify function */
971 if (!dllist_is_empty(&sCmdCompNotifyHead))
973 PDLLIST_NODE psNode = dllist_get_next_node(&sCmdCompNotifyHead);
975 /* some device did not unregistered properly */
976 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: Notify list for cmd complete is not empty!!"));
978 /* clean the nodes anyway */
979 while (psNode != IMG_NULL)
981 PVRSRV_CMDCOMP_NOTIFY *psNotify;
983 dllist_remove_node(psNode);
985 psNotify = IMG_CONTAINER_OF(psNode, PVRSRV_CMDCOMP_NOTIFY, sListNode);
988 psNode = dllist_get_next_node(&sCmdCompNotifyHead);
992 OSLockDestroy(gpsPVRSRVData->hPowerLock);
994 eError = PVRSRVHandleDeInit();
995 if (eError != PVRSRV_OK)
997 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed"));
1000 #if !defined(UNDER_WDDM) && defined(SUPPORT_DISPLAY_CLASS)
1001 eError = DCDeInit();
1002 if (eError != PVRSRV_OK)
1004 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: DCInit() failed"));
1009 eError = PMRDeInit();
1010 if (eError != PVRSRV_OK)
1012 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PMRDeInit() failed"));
1015 #if defined(PVR_RI_DEBUG)
1019 eError = PVRSRVConnectionDeInit();
1020 if (eError != PVRSRV_OK)
1022 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVConnectionDataDeInit failed"));
1029 for (i=0;i<gpsPVRSRVData->ui32RegisteredPhysHeaps;i++)
1031 PhysHeapUnregister(gpsPVRSRVData->apsRegisteredPhysHeaps[i]);
1033 eError = PhysHeapDeinit();
1034 if (eError != PVRSRV_OK)
1036 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PhysHeapDeinit() failed"));
1039 OSFreeMem(gpsPVRSRVData);
1040 gpsPVRSRVData = IMG_NULL;
1043 PVRSRV_ERROR LMA_MMUPxAlloc(PVRSRV_DEVICE_NODE *psDevNode, IMG_SIZE_T uiSize,
1044 Px_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr)
1047 RA_BASE_T uiCardAddr;
1048 RA_LENGTH_T uiActualSize;
1050 PVR_ASSERT((uiSize & OSGetPageMask()) == 0);
1052 bSuccess = RA_Alloc(psDevNode->psLocalDevMemArena,
1058 IMG_NULL); /* No private handle */
1060 PVR_ASSERT(uiSize == uiActualSize);
1062 psMemHandle->u.ui64Handle = uiCardAddr;
1063 psDevPAddr->uiAddr = (IMG_UINT64) uiCardAddr;
1067 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
1068 #if !defined(PVRSRV_ENABLE_MEMORY_STATS)
1069 /* Allocation is done a page at a time */
1070 PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA, OSGetPageSize());
1072 IMG_CPU_PHYADDR sCpuPAddr;
1073 sCpuPAddr.uiAddr = psDevPAddr->uiAddr;
1074 PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA,
1084 return PVRSRV_ERROR_OUT_OF_MEMORY;
1087 IMG_VOID LMA_MMUPxFree(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle)
1089 RA_BASE_T uiCardAddr = (RA_BASE_T) psMemHandle->u.ui64Handle;
1091 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
1092 #if !defined(PVRSRV_ENABLE_MEMORY_STATS)
1093 /* Allocation is done a page at a time */
1094 PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA, OSGetPageSize());
1096 PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA, (IMG_UINT64)uiCardAddr);
1100 RA_Free(psDevNode->psLocalDevMemArena, uiCardAddr);
1103 PVRSRV_ERROR LMA_MMUPxMap(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle,
1104 IMG_SIZE_T uiSize, IMG_DEV_PHYADDR *psDevPAddr,
1107 IMG_CPU_PHYADDR sCpuPAddr;
1108 PVR_UNREFERENCED_PARAMETER(psMemHandle);
1109 PVR_UNREFERENCED_PARAMETER(uiSize);
1111 PhysHeapDevPAddrToCpuPAddr(psDevNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL], &sCpuPAddr, psDevPAddr);
1112 *pvPtr = OSMapPhysToLin(sCpuPAddr,
1115 if (*pvPtr == IMG_NULL)
1117 return PVRSRV_ERROR_OUT_OF_MEMORY;
1121 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
1122 #if !defined(PVRSRV_ENABLE_MEMORY_STATS)
1123 /* Mapping is done a page at a time */
1124 PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA, OSGetPageSize());
1127 PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA,
1139 IMG_VOID LMA_MMUPxUnmap(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle,
1142 PVR_UNREFERENCED_PARAMETER(psMemHandle);
1143 PVR_UNREFERENCED_PARAMETER(psDevNode);
1145 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
1146 #if !defined(PVRSRV_ENABLE_MEMORY_STATS)
1147 /* Mapping is done a page at a time */
1148 PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA, OSGetPageSize());
1150 PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA, (IMG_UINT64)(IMG_UINTPTR_T)pvPtr);
1154 OSUnMapPhysToLin(pvPtr, OSGetPageSize(), 0);
1158 ******************************************************************************
1160 @Function PVRSRVRegisterDevice
1164 registers a device with the system
1166 @Input psDevConfig : Device configuration structure
1168 @Return PVRSRV_ERROR :
1170 ******************************************************************************/
1171 static PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PVRSRV_DEVICE_CONFIG *psDevConfig)
1173 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
1174 PVRSRV_ERROR eError;
1175 PVRSRV_DEVICE_NODE *psDeviceNode;
1176 PVRSRV_DEVICE_PHYS_HEAP physHeapIndex;
1178 /* Allocate device node */
1179 psDeviceNode = OSAllocMem(sizeof(PVRSRV_DEVICE_NODE));
1180 if (psDeviceNode == IMG_NULL)
1182 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode"));
1183 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1186 OSMemSet(psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
1188 /* set device state */
1189 psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_INIT;
1191 eError = PhysHeapAcquire(psDevConfig->aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL], &psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]);
1192 if (eError != PVRSRV_OK)
1194 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to acquire PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL physical memory heap"));
1197 eError = PhysHeapAcquire(psDevConfig->aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL], &psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL]);
1198 if (eError != PVRSRV_OK)
1200 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to acquire PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL physical memory heap"));
1204 /* Do we have card memory? If so create an RA to manage it */
1205 if (PhysHeapGetType(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]) == PHYS_HEAP_TYPE_LMA)
1209 IMG_CPU_PHYADDR sCpuPAddr;
1210 IMG_UINT64 ui64Size;
1212 eError = PhysHeapGetAddress(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL], &sCpuPAddr);
1213 if (eError != PVRSRV_OK)
1215 /* We can only get here if there is a bug in this module */
1216 PVR_ASSERT(IMG_FALSE);
1220 eError = PhysHeapGetSize(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL], &ui64Size);
1221 if (eError != PVRSRV_OK)
1223 /* We can only get here if there is a bug in this module */
1224 PVR_ASSERT(IMG_FALSE);
1229 PVR_DPF((PVR_DBG_MESSAGE, "Creating RA for card memory 0x%016llx-0x%016llx",
1230 (IMG_UINT64) sCpuPAddr.uiAddr, sCpuPAddr.uiAddr + ui64Size));
1232 OSSNPrintf(psDeviceNode->szRAName, sizeof(psDeviceNode->szRAName),
1234 psDevConfig->pszName);
1237 if (psDevConfig->uiFlags & PVRSRV_DEVICE_CONFIG_LMA_USE_CPU_ADDR)
1239 uBase = sCpuPAddr.uiAddr;
1242 uSize = (RA_LENGTH_T) ui64Size;
1243 PVR_ASSERT(uSize == ui64Size);
1245 psDeviceNode->psLocalDevMemArena =
1246 RA_Create(psDeviceNode->szRAName,
1247 OSGetPageShift(), /* Use host page size, keeps things simple */
1248 RA_LOCKCLASS_0, /* This arena doesn't use any other arenas. */
1249 IMG_NULL, /* No Import */
1250 IMG_NULL, /* No free import */
1251 IMG_NULL); /* No import handle */
1253 if (psDeviceNode->psLocalDevMemArena == IMG_NULL)
1255 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1259 if (!RA_Add(psDeviceNode->psLocalDevMemArena, uBase, uSize, 0 /* No flags */, IMG_NULL /* No private data */))
1261 RA_Delete(psDeviceNode->psLocalDevMemArena);
1262 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1267 psDeviceNode->pfnMMUPxAlloc = LMA_MMUPxAlloc;
1268 psDeviceNode->pfnMMUPxFree = LMA_MMUPxFree;
1269 psDeviceNode->pfnMMUPxMap = LMA_MMUPxMap;
1270 psDeviceNode->pfnMMUPxUnmap = LMA_MMUPxUnmap;
1271 psDeviceNode->uiMMUPxLog2AllocGran = OSGetPageShift();
1272 psDeviceNode->ui32Flags = PRVSRV_DEVICE_FLAGS_LMA;
1273 psDeviceNode->pfnCreateRamBackedPMR[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL] = PhysmemNewLocalRamBackedPMR;
1277 PVR_DPF((PVR_DBG_MESSAGE, "===== OS System memory only, no local card memory"));
1279 /* else we only have OS system memory */
1280 psDeviceNode->pfnMMUPxAlloc = OSMMUPxAlloc;
1281 psDeviceNode->pfnMMUPxFree = OSMMUPxFree;
1282 psDeviceNode->pfnMMUPxMap = OSMMUPxMap;
1283 psDeviceNode->pfnMMUPxUnmap = OSMMUPxUnmap;
1284 psDeviceNode->pfnCreateRamBackedPMR[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL] = PhysmemNewOSRamBackedPMR;
1287 if (PhysHeapGetType(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL]) == PHYS_HEAP_TYPE_LMA)
1289 PVR_DPF((PVR_DBG_MESSAGE, "===== Local card memory only, no OS system memory"));
1290 psDeviceNode->pfnCreateRamBackedPMR[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL] = PhysmemNewLocalRamBackedPMR;
1294 PVR_DPF((PVR_DBG_MESSAGE, "===== OS System memory, 2nd phys heap"));
1295 psDeviceNode->pfnCreateRamBackedPMR[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL] = PhysmemNewOSRamBackedPMR;
1299 psDeviceNode->pszMMUPxPDumpMemSpaceName = PhysHeapPDumpMemspaceName(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]);
1300 psDeviceNode->uiMMUPxLog2AllocGran = OSGetPageShift();
1302 /* Add the devnode to our list so we can unregister it later */
1303 psPVRSRVData->apsRegisteredDevNodes[psPVRSRVData->ui32RegisteredDevices++] = psDeviceNode;
1305 psDeviceNode->ui32RefCount = 1;
1306 psDeviceNode->psDevConfig = psDevConfig;
1308 /* all devices need a unique identifier */
1309 AllocateDeviceID(psPVRSRVData, &psDeviceNode->sDevId.ui32DeviceIndex);
1311 /* Device type and class will be setup during this callback */
1312 eError = sRegisterDevice[psDevConfig->eDeviceType](psDeviceNode);
1313 if (eError != PVRSRV_OK)
1315 /*not nulling pointer, out of scope*/
1316 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device"));
1317 eError = PVRSRV_ERROR_DEVICE_REGISTER_FAILED;
1322 PVR_DPF((PVR_DBG_MESSAGE, "Registered device %d of type %d", psDeviceNode->sDevId.ui32DeviceIndex, psDeviceNode->sDevId.eDeviceType));
1323 PVR_DPF((PVR_DBG_MESSAGE, "Register bank address = 0x%08lx", (unsigned long)psDevConfig->sRegsCpuPBase.uiAddr));
1324 PVR_DPF((PVR_DBG_MESSAGE, "IRQ = %d", psDevConfig->ui32IRQ));
1326 /* and finally insert the device into the dev-list */
1327 List_PVRSRV_DEVICE_NODE_Insert(&psPVRSRVData->psDeviceNodeList, psDeviceNode);
1329 /* set device state */
1330 psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_ACTIVE;
1334 if (psDeviceNode->psLocalDevMemArena)
1336 RA_Delete(psDeviceNode->psLocalDevMemArena);
1340 for(physHeapIndex=0; physHeapIndex < PVRSRV_DEVICE_PHYS_HEAP_LAST; physHeapIndex++)
1342 if (psDeviceNode->apsPhysHeap[physHeapIndex])
1344 PhysHeapRelease(psDeviceNode->apsPhysHeap[physHeapIndex]);
1347 OSFreeMem(psDeviceNode);
1352 PVRSRV_ERROR IMG_CALLCONV PVRSRVSysPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState, IMG_BOOL bForced)
1354 PVRSRV_ERROR eError = PVRSRV_OK;
1356 PVR_UNREFERENCED_PARAMETER(bForced);
1358 if (gpsSysConfig->pfnSysPrePowerState)
1360 eError = gpsSysConfig->pfnSysPrePowerState(eNewPowerState);
1365 PVRSRV_ERROR IMG_CALLCONV PVRSRVSysPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState, IMG_BOOL bForced)
1367 PVRSRV_ERROR eError = PVRSRV_OK;
1369 PVR_UNREFERENCED_PARAMETER(bForced);
1371 if (gpsSysConfig->pfnSysPostPowerState)
1373 eError = gpsSysConfig->pfnSysPostPowerState(eNewPowerState);
1378 PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterExtDevice(PVRSRV_DEVICE_NODE *psDeviceNode,
1379 IMG_UINT32 *pui32DeviceIndex,
1380 IMG_UINT32 ui32PhysHeapID)
1382 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
1383 PHYS_HEAP *psPhysHeapTmp;
1384 PVRSRV_DEVICE_PHYS_HEAP eDevPhysHeap;
1385 PVRSRV_ERROR eError;
1387 psDeviceNode->ui32RefCount = 1;
1389 eError = PhysHeapAcquire(ui32PhysHeapID, &psPhysHeapTmp);
1390 if (eError != PVRSRV_OK)
1392 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterExtDevice: Failed to acquire physical memory heap"));
1395 if (PhysHeapGetType(psPhysHeapTmp) == PHYS_HEAP_TYPE_LMA)
1397 eDevPhysHeap = PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL;
1401 eDevPhysHeap = PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL;
1403 psDeviceNode->apsPhysHeap[eDevPhysHeap] = psPhysHeapTmp;
1405 /* allocate a unique device id */
1406 eError = AllocateDeviceID(psPVRSRVData, &psDeviceNode->sDevId.ui32DeviceIndex);
1407 if (eError != PVRSRV_OK)
1409 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterExtDevice: Failed to allocate Device ID"));
1413 if (pui32DeviceIndex)
1415 *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
1418 List_PVRSRV_DEVICE_NODE_Insert(&psPVRSRVData->psDeviceNodeList, psDeviceNode);
1422 PhysHeapRelease(psDeviceNode->apsPhysHeap[eDevPhysHeap]);
1427 IMG_VOID IMG_CALLCONV PVRSRVUnregisterExtDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
1429 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
1430 PVRSRV_DEVICE_PHYS_HEAP eDevPhysHeap;
1432 List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
1433 (IMG_VOID)FreeDeviceID(psPVRSRVData, psDeviceNode->sDevId.ui32DeviceIndex);
1434 for (eDevPhysHeap = 0; eDevPhysHeap < PVRSRV_DEVICE_PHYS_HEAP_LAST; eDevPhysHeap++)
1436 if (psDeviceNode->apsPhysHeap[eDevPhysHeap])
1438 PhysHeapRelease(psDeviceNode->apsPhysHeap[eDevPhysHeap]);
1443 static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
1445 PVRSRV_ERROR eError;
1446 PVRSRV_DEV_POWER_STATE ePowState;
1448 ePowState = va_arg(va, PVRSRV_DEV_POWER_STATE);
1450 eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
1454 if (eError != PVRSRV_OK)
1456 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (%s, device index: %d)",
1457 PVRSRVGetErrorStringKM(eError),
1458 psDeviceNode->sDevId.ui32DeviceIndex));
1464 /*wraps the PVRSRVDevInitCompatCheck call and prints a debugging message if failed*/
1465 static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_Any_va(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
1467 PVRSRV_ERROR eError;
1468 IMG_UINT32 *pui32ClientBuildOptions;
1470 pui32ClientBuildOptions = va_arg(va, IMG_UINT32*);
1472 eError = PVRSRVDevInitCompatCheck(psDeviceNode, *pui32ClientBuildOptions);
1473 if (eError != PVRSRV_OK)
1475 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
1482 ******************************************************************************
1484 @Function PVRSRVFinaliseSystem
1488 Final part of system initialisation.
1490 @Input ui32DevIndex : Index to the required device
1492 @Return PVRSRV_ERROR :
1494 ******************************************************************************/
1495 PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful, IMG_UINT32 ui32ClientBuildOptions)
1497 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
1498 PVRSRV_ERROR eError;
1501 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem"));
1503 if (bInitSuccessful)
1505 for (i=0;i<psPVRSRVData->ui32RegisteredDevices;i++)
1507 PVRSRV_DEVICE_NODE *psDeviceNode = psPVRSRVData->apsRegisteredDevNodes[i];
1509 SyncPrimContextCreate(IMG_NULL,
1511 &psDeviceNode->hSyncPrimContext);
1513 /* Allocate general purpose sync primitive */
1514 eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext, &psDeviceNode->psSyncPrim, "pvrsrv dev general");
1515 if (eError != PVRSRV_OK)
1517 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed to allocate sync primitive with error (%u)", eError));
1520 /* Allocate PreKick sync primitive */
1521 eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext, &psDeviceNode->psSyncPrimPreKick, "pvrsrv pre kick");
1522 if (eError != PVRSRV_OK)
1524 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed to allocate PreKick sync primitive with error (%u)", eError));
1530 eError = PVRSRVPowerLock();
1531 if (eError != PVRSRV_OK)
1533 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem_SetPowerState_AnyCb: Failed to acquire power lock"));
1537 /* Always ensure a single power on command appears in the pdump.
1538 * This should be the only power related call outside of PDUMPPOWCMDSTART/END.
1539 * Place all devices into ON power state. */
1540 eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psPVRSRVData->psDeviceNodeList,
1541 &PVRSRVFinaliseSystem_SetPowerState_AnyCb,
1542 PVRSRV_DEV_POWER_STATE_ON);
1543 if (eError != PVRSRV_OK)
1545 PVRSRVPowerUnlock();
1549 /* Verify firmware compatibility for devices */
1550 eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psPVRSRVData->psDeviceNodeList,
1551 &PVRSRVFinaliseSystem_CompatCheck_Any_va,
1552 &ui32ClientBuildOptions);
1553 if (eError != PVRSRV_OK)
1555 PVRSRVPowerUnlock();
1556 PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, IMG_NULL);
1561 /* Place all devices into their default power state. */
1562 eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psPVRSRVData->psDeviceNodeList,
1563 &PVRSRVFinaliseSystem_SetPowerState_AnyCb,
1564 PVRSRV_DEV_POWER_STATE_DEFAULT);
1567 if (eError != PVRSRV_OK)
1569 PVRSRVPowerUnlock();
1573 PVRSRVPowerUnlock();
1577 eError = PDumpStopInitPhaseKM(IMG_SRV_INIT);
1579 if(eError != PVRSRV_OK)
1581 PVR_DPF((PVR_DBG_ERROR, "Failed to stop PDump init phase"));
1589 PVRSRV_ERROR IMG_CALLCONV PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode,IMG_UINT32 ui32ClientBuildOptions)
1591 /* Only check devices which specify a compatibility check callback */
1592 if (psDeviceNode->pfnInitDeviceCompatCheck)
1593 return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode, ui32ClientBuildOptions);
1599 ******************************************************************************
1601 @Function PVRSRVAcquireDeviceDataKM
1605 Matchs a device given a device type and a device index.
1607 @input psDeviceNode :The device node to be matched.
1609 @Input va : Variable argument list with:
1610 eDeviceType : Required device type. If type is unknown use ui32DevIndex
1611 to locate device data
1613 ui32DevIndex : Index to the required device obtained from the
1614 PVRSRVEnumerateDevice function
1616 @Return PVRSRV_ERROR :
1618 ******************************************************************************/
1619 static IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
1621 PVRSRV_DEVICE_TYPE eDeviceType;
1622 IMG_UINT32 ui32DevIndex;
1624 eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE);
1625 ui32DevIndex = va_arg(va, IMG_UINT32);
1627 if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN &&
1628 psDeviceNode->sDevId.eDeviceType == eDeviceType) ||
1629 (eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN &&
1630 psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex))
1632 return psDeviceNode;
1641 ******************************************************************************
1643 @Function PVRSRVAcquireDeviceDataKM
1647 Returns device information
1649 @Input ui32DevIndex : Index to the required device obtained from the
1650 PVRSRVEnumerateDevice function
1652 @Input eDeviceType : Required device type. If type is unknown use ui32DevIndex
1653 to locate device data
1655 @Output *phDevCookie : Dev Cookie
1658 @Return PVRSRV_ERROR :
1660 ******************************************************************************/
1662 PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex,
1663 PVRSRV_DEVICE_TYPE eDeviceType,
1664 IMG_HANDLE *phDevCookie)
1666 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
1667 PVRSRV_DEVICE_NODE *psDeviceNode;
1669 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM"));
1671 /* Find device in the list */
1672 psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
1673 &PVRSRVAcquireDeviceDataKM_Match_AnyVaCb,
1680 /* device can't be found in the list so it isn't in the system */
1681 PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present"));
1682 return PVRSRV_ERROR_INIT_FAILURE;
1687 PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
1689 /* return the dev cookie? */
1692 *phDevCookie = (IMG_HANDLE)psDeviceNode;
1699 PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseDeviceDataKM (IMG_HANDLE hDevCookie)
1701 PVR_UNREFERENCED_PARAMETER(hDevCookie);
1704 Empty release body as the lifetime of this resource accessed by
1705 PVRSRVAcquireDeviceDataKM is linked to driver lifetime, not API allocation.
1706 This is one reason why this type crosses the bridge with a shared handle.
1707 Thus no server release action is required, just bridge action to ensure
1708 associated handle is freed.
1714 ******************************************************************************
1716 @Function PVRSRVUnregisterDevice
1720 This De-inits device
1722 @Input ui32DevIndex : Index to the required device
1724 @Return PVRSRV_ERROR :
1726 ******************************************************************************/
1727 static PVRSRV_ERROR IMG_CALLCONV PVRSRVUnregisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
1729 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
1730 PVRSRV_DEVICE_PHYS_HEAP ePhysHeapIdx;
1731 PVRSRV_ERROR eError;
1733 eError = PVRSRVPowerLock();
1734 if (eError != PVRSRV_OK)
1736 PVR_DPF((PVR_DBG_ERROR,"PVRSRVUnregisterDevice: Failed to acquire power lock"));
1741 Power down the device if necessary.
1743 eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
1744 PVRSRV_DEV_POWER_STATE_OFF,
1747 PVRSRVPowerUnlock();
1749 if (eError != PVRSRV_OK)
1751 PVR_DPF((PVR_DBG_ERROR,"PVRSRVUnregisterDevice: Failed PVRSRVSetDevicePowerStateKM call (%s). Dump debug.", PVRSRVGetErrorStringKM(eError)));
1753 PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, IMG_NULL);
1755 /* If the driver is okay then return the error, otherwise we can ignore this error. */
1756 if (PVRSRVGetPVRSRVData()->eServicesState == PVRSRV_SERVICES_STATE_OK)
1762 PVR_DPF((PVR_DBG_MESSAGE,"PVRSRVUnregisterDevice: Will continue to unregister as driver status is not OK"));
1769 sUnregisterDevice[psDeviceNode->sDevId.eDeviceType](psDeviceNode);
1771 /* Remove RA for local card memory */
1772 if (psDeviceNode->psLocalDevMemArena)
1774 RA_Delete(psDeviceNode->psLocalDevMemArena);
1777 /* remove node from list */
1778 List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
1780 /* deallocate id and memory */
1781 (IMG_VOID)FreeDeviceID(psPVRSRVData, psDeviceNode->sDevId.ui32DeviceIndex);
1783 for (ePhysHeapIdx = 0; ePhysHeapIdx < PVRSRV_DEVICE_PHYS_HEAP_LAST; ePhysHeapIdx++)
1785 if (psDeviceNode->apsPhysHeap[ePhysHeapIdx])
1787 PhysHeapRelease(psDeviceNode->apsPhysHeap[ePhysHeapIdx]);
1791 OSFreeMem(psDeviceNode);
1792 /*not nulling pointer, out of scope*/
1802 PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr,
1803 IMG_UINT32 ui32Value,
1804 IMG_UINT32 ui32Mask,
1805 IMG_UINT32 ui32Timeoutus,
1806 IMG_UINT32 ui32PollPeriodus,
1807 IMG_BOOL bAllowPreemption)
1809 #if defined(NO_HARDWARE)
1810 PVR_UNREFERENCED_PARAMETER(pui32LinMemAddr);
1811 PVR_UNREFERENCED_PARAMETER(ui32Value);
1812 PVR_UNREFERENCED_PARAMETER(ui32Mask);
1813 PVR_UNREFERENCED_PARAMETER(ui32Timeoutus);
1814 PVR_UNREFERENCED_PARAMETER(ui32PollPeriodus);
1815 PVR_UNREFERENCED_PARAMETER(bAllowPreemption);
1818 IMG_UINT32 ui32ActualValue = 0xFFFFFFFFU; /* Initialiser only required to prevent incorrect warning */
1820 if (bAllowPreemption)
1822 PVR_ASSERT(ui32PollPeriodus >= 1000);
1825 LOOP_UNTIL_TIMEOUT(ui32Timeoutus)
1827 ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
1828 if(ui32ActualValue == ui32Value)
1833 if (gpsPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
1835 return PVRSRV_ERROR_TIMEOUT;
1838 if (bAllowPreemption)
1840 OSSleepms(ui32PollPeriodus / 1000);
1844 OSWaitus(ui32PollPeriodus);
1846 } END_LOOP_UNTIL_TIMEOUT();
1848 PVR_DPF((PVR_DBG_ERROR,"PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).",
1849 ui32Value, ui32ActualValue, ui32Mask));
1851 return PVRSRV_ERROR_TIMEOUT;
1852 #endif /* NO_HARDWARE */
1857 PVRSRVPollForValueKM
1860 PVRSRV_ERROR IMG_CALLCONV PVRSRVPollForValueKM (volatile IMG_UINT32 *pui32LinMemAddr,
1861 IMG_UINT32 ui32Value,
1862 IMG_UINT32 ui32Mask)
1864 return PollForValueKM(pui32LinMemAddr, ui32Value, ui32Mask,
1866 MAX_HW_TIME_US/WAIT_TRY_COUNT,
1871 PVRSRVWaitForValueKM
1874 PVRSRV_ERROR IMG_CALLCONV PVRSRVWaitForValueKM (volatile IMG_UINT32 *pui32LinMemAddr,
1875 IMG_UINT32 ui32Value,
1876 IMG_UINT32 ui32Mask)
1878 #if defined(NO_HARDWARE)
1879 PVR_UNREFERENCED_PARAMETER(pui32LinMemAddr);
1880 PVR_UNREFERENCED_PARAMETER(ui32Value);
1881 PVR_UNREFERENCED_PARAMETER(ui32Mask);
1885 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
1886 IMG_HANDLE hOSEvent;
1887 PVRSRV_ERROR eError;
1888 PVRSRV_ERROR eErrorWait;
1889 IMG_UINT32 ui32ActualValue;
1891 eError = OSEventObjectOpen(psPVRSRVData->hGlobalEventObject, &hOSEvent);
1892 if (eError != PVRSRV_OK)
1894 PVR_DPF((PVR_DBG_ERROR,"PVRSRVWaitForValueKM: Failed to setup EventObject with error (%d)", eError));
1895 goto EventObjectOpenError;
1898 eError = PVRSRV_ERROR_TIMEOUT;
1900 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
1902 ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
1904 if (ui32ActualValue == ui32Value)
1906 /* Expected value has been found */
1910 else if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
1912 /* Services in bad state, don't wait any more */
1913 eError = PVRSRV_ERROR_NOT_READY;
1918 /* wait for event and retry */
1919 eErrorWait = OSEventObjectWait(hOSEvent);
1920 if (eErrorWait != PVRSRV_OK && eErrorWait != PVRSRV_ERROR_TIMEOUT)
1922 PVR_DPF((PVR_DBG_WARNING,"PVRSRVWaitForValueKM: Waiting for value failed with error %d. Expected 0x%x but found 0x%x (Mask 0x%08x). Retrying",
1929 } END_LOOP_UNTIL_TIMEOUT();
1931 OSEventObjectClose(hOSEvent);
1933 /* One last check incase the object wait ended after the loop timeout... */
1934 if (eError != PVRSRV_OK && (*pui32LinMemAddr & ui32Mask) == ui32Value)
1939 /* Provide event timeout information to aid the Device Watchdog Thread... */
1940 if (eError == PVRSRV_OK)
1942 psPVRSRVData->ui32GEOConsecutiveTimeouts = 0;
1944 else if (eError == PVRSRV_ERROR_TIMEOUT)
1946 psPVRSRVData->ui32GEOConsecutiveTimeouts++;
1949 EventObjectOpenError:
1953 #endif /* NO_HARDWARE */
1956 #if !defined(NO_HARDWARE)
1957 static IMG_BOOL _CheckStatus(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
1959 PVRSRV_CMDCOMP_HANDLE hCmdCompCallerHandle = (PVRSRV_CMDCOMP_HANDLE) pvCallbackData;
1960 PVRSRV_CMDCOMP_NOTIFY *psNotify;
1962 psNotify = IMG_CONTAINER_OF(psNode, PVRSRV_CMDCOMP_NOTIFY, sListNode);
1964 /* A device has finished some processing, check if that unblocks other devices */
1965 if (hCmdCompCallerHandle != psNotify->hCmdCompHandle)
1967 psNotify->pfnCmdCompleteNotify(psNotify->hCmdCompHandle);
1970 /* keep processing until the end of the list */
1975 IMG_VOID IMG_CALLCONV PVRSRVCheckStatus(PVRSRV_CMDCOMP_HANDLE hCmdCompCallerHandle)
1977 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
1979 /* notify any registered device to check if block work items can now proceed */
1980 #if !defined(NO_HARDWARE)
1981 OSWRLockAcquireRead(hNotifyLock, GLOBAL_NOTIFY);
1982 dllist_foreach_node(&sCmdCompNotifyHead, _CheckStatus, hCmdCompCallerHandle);
1983 OSWRLockReleaseRead(hNotifyLock);
1986 /* signal global event object */
1987 if (psPVRSRVData->hGlobalEventObject)
1989 IMG_HANDLE hOSEventKM = psPVRSRVData->hGlobalEventObject;
1992 OSEventObjectSignal(hOSEventKM);
1997 PVRSRV_ERROR IMG_CALLCONV PVRSRVKickDevicesKM(IMG_VOID)
1999 PVR_DPF((PVR_DBG_ERROR, "PVRSRVKickDevicesKM"));
2000 PVRSRVCheckStatus(IMG_NULL);
2005 ******************************************************************************
2007 @Function PVRSRVGetErrorStringKM
2009 @Description Returns a text string relating to the PVRSRV_ERROR enum.
2011 @Note case statement used rather than an indexed arrary to ensure text is
2012 synchronised with the correct enum
2014 @Input eError : PVRSRV_ERROR enum
2016 @Return const IMG_CHAR * : Text string
2018 @Note Must be kept in sync with servicesext.h
2020 ******************************************************************************/
2023 const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError)
2032 #include "pvrsrv_errors.h"
2035 return "Unknown PVRSRV error number";
2040 PVRSRVSystemDebugInfo
2042 PVRSRV_ERROR PVRSRVSystemDebugInfo( DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
2044 return SysDebugInfo(gpsSysConfig, pfnDumpDebugPrintf);
2050 const IMG_CHAR *PVRSRVGetSystemName(IMG_VOID)
2052 return gpsSysConfig->pszSystemName;
2056 PVRSRVSystemHasCacheSnooping
2058 IMG_BOOL PVRSRVSystemHasCacheSnooping(IMG_VOID)
2060 if (gpsSysConfig->eCacheSnoopingMode != PVRSRV_SYSTEM_SNOOP_NONE)
2067 IMG_BOOL PVRSRVSystemSnoopingOfCPUCache(IMG_VOID)
2069 if ((gpsSysConfig->eCacheSnoopingMode == PVRSRV_SYSTEM_SNOOP_CPU_ONLY) ||
2070 (gpsSysConfig->eCacheSnoopingMode == PVRSRV_SYSTEM_SNOOP_CROSS))
2077 IMG_BOOL PVRSRVSystemSnoopingOfDeviceCache(IMG_VOID)
2079 if ((gpsSysConfig->eCacheSnoopingMode == PVRSRV_SYSTEM_SNOOP_DEVICE_ONLY) ||
2080 (gpsSysConfig->eCacheSnoopingMode == PVRSRV_SYSTEM_SNOOP_CROSS))
2088 PVRSRVSystemWaitCycles
2090 IMG_VOID PVRSRVSystemWaitCycles(PVRSRV_DEVICE_CONFIG *psDevConfig, IMG_UINT32 ui32Cycles)
2093 IMG_UINT32 ui32Delayus = 1;
2095 /* obtain the device freq */
2096 if (psDevConfig->pfnClockFreqGet != IMG_NULL)
2098 IMG_UINT32 ui32DeviceFreq;
2100 ui32DeviceFreq = psDevConfig->pfnClockFreqGet(psDevConfig->hSysData);
2102 ui32Delayus = (ui32Cycles*1000000)/ui32DeviceFreq;
2104 if (ui32Delayus == 0)
2110 OSWaitus(ui32Delayus);
2114 PVRSRVRegisterCmdCompleteNotify
2116 PVRSRV_ERROR PVRSRVRegisterCmdCompleteNotify(IMG_HANDLE *phNotify, PFN_CMDCOMP_NOTIFY pfnCmdCompleteNotify, PVRSRV_CMDCOMP_HANDLE hCmdCompHandle)
2118 PVRSRV_CMDCOMP_NOTIFY *psNotify;
2120 if ((phNotify == IMG_NULL) || (pfnCmdCompleteNotify == IMG_NULL) || (hCmdCompHandle == IMG_NULL))
2122 PVR_DPF((PVR_DBG_ERROR,"%s: Bad arguments (%p, %p, %p)", __FUNCTION__, phNotify, pfnCmdCompleteNotify, hCmdCompHandle));
2123 return PVRSRV_ERROR_INVALID_PARAMS;
2126 psNotify = OSAllocMem(sizeof(*psNotify));
2127 if (psNotify == IMG_NULL)
2129 PVR_DPF((PVR_DBG_ERROR,"%s: Not enough memory to allocate CmdCompleteNotify function", __FUNCTION__));
2130 return PVRSRV_ERROR_OUT_OF_MEMORY;
2133 /* Set-up the notify data */
2134 psNotify->hCmdCompHandle = hCmdCompHandle;
2135 psNotify->pfnCmdCompleteNotify = pfnCmdCompleteNotify;
2137 /* Add it to the list of Notify functions */
2138 OSWRLockAcquireWrite(hNotifyLock, GLOBAL_NOTIFY);
2139 dllist_add_to_tail(&sCmdCompNotifyHead, &psNotify->sListNode);
2140 OSWRLockReleaseWrite(hNotifyLock);
2142 *phNotify = psNotify;
2148 PVRSRVUnregisterCmdCompleteNotify
2150 PVRSRV_ERROR PVRSRVUnregisterCmdCompleteNotify(IMG_HANDLE hNotify)
2152 PVRSRV_CMDCOMP_NOTIFY *psNotify = (PVRSRV_CMDCOMP_NOTIFY*) hNotify;
2154 if (psNotify == IMG_NULL)
2156 PVR_DPF((PVR_DBG_ERROR,"%s: Bad arguments (%p)", __FUNCTION__, hNotify));
2157 return PVRSRV_ERROR_INVALID_PARAMS;
2160 /* remove the node from the list */
2161 OSWRLockAcquireWrite(hNotifyLock, GLOBAL_NOTIFY);
2162 dllist_remove_node(&psNotify->sListNode);
2163 OSWRLockReleaseWrite(hNotifyLock);
2165 /* free the notify structure that holds the node */
2166 OSFreeMem(psNotify);
2172 static IMG_VOID _SysDebugRequestNotify(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, IMG_UINT32 ui32VerbLevel)
2174 PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA*) hDebugRequestHandle;
2175 DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf = IMG_NULL;
2177 pfnDumpDebugPrintf = g_pfnDumpDebugPrintf;
2178 /* only dump info on the lowest verbosity level */
2179 if (ui32VerbLevel != DEBUG_REQUEST_VERBOSITY_LOW)
2184 PVR_DUMPDEBUG_LOG(("DDK info: %s (%s) %s", PVRVERSION_STRING, PVR_BUILD_TYPE, PVR_BUILD_DIR));
2186 /* Services state */
2187 switch (psPVRSRVData->eServicesState)
2189 case PVRSRV_SERVICES_STATE_OK:
2191 PVR_DUMPDEBUG_LOG(("Services State: OK"));
2195 case PVRSRV_SERVICES_STATE_BAD:
2197 PVR_DUMPDEBUG_LOG(("Services State: BAD"));
2203 PVR_DUMPDEBUG_LOG(("Services State: UNKNOWN (%d)", psPVRSRVData->eServicesState));
2209 switch (psPVRSRVData->eCurrentPowerState)
2211 case PVRSRV_SYS_POWER_STATE_OFF:
2213 PVR_DUMPDEBUG_LOG(("System Power State: OFF"));
2216 case PVRSRV_SYS_POWER_STATE_ON:
2218 PVR_DUMPDEBUG_LOG(("System Power State: ON"));
2223 PVR_DUMPDEBUG_LOG(("System Power State: UNKNOWN (%d)", psPVRSRVData->eCurrentPowerState));
2228 /* Dump system specific debug info */
2229 PVRSRVSystemDebugInfo(pfnDumpDebugPrintf);
2233 static IMG_BOOL _DebugRequest(PDLLIST_NODE psNode, IMG_PVOID hVerbLevel)
2235 IMG_UINT32 *pui32VerbLevel = (IMG_UINT32 *) hVerbLevel;
2236 PVRSRV_DBGREQ_NOTIFY *psNotify;
2238 psNotify = IMG_CONTAINER_OF(psNode, PVRSRV_DBGREQ_NOTIFY, sListNode);
2240 psNotify->pfnDbgRequestNotify(psNotify->hDbgRequestHandle, *pui32VerbLevel);
2242 /* keep processing until the end of the list */
2249 IMG_VOID IMG_CALLCONV PVRSRVDebugRequest(IMG_UINT32 ui32VerbLevel, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
2253 g_pfnDumpDebugPrintf = pfnDumpDebugPrintf;
2256 /* notify any registered device to check if block work items can now proceed */
2257 /* Lock the lists */
2258 OSWRLockAcquireRead(g_hDbgNotifyLock, GLOBAL_DBGNOTIFY);
2260 PVR_DUMPDEBUG_LOG(("------------[ PVR DBG: START ]------------"));
2262 /* For each verbosity level */
2263 for (j=0;j<(ui32VerbLevel+1);j++)
2265 /* For each requester */
2266 for (i=0;i<g_psDebugTable->ui32RequestCount;i++)
2268 dllist_foreach_node(&g_psDebugTable->asEntry[i].sListHead, _DebugRequest, &j);
2271 PVR_DUMPDEBUG_LOG(("------------[ PVR DBG: END ]------------"));
2273 /* Unlock the lists */
2274 OSWRLockReleaseRead(g_hDbgNotifyLock);
2278 PVRSRVRegisterDebugRequestNotify
2280 PVRSRV_ERROR PVRSRVRegisterDbgRequestNotify(IMG_HANDLE *phNotify, PFN_DBGREQ_NOTIFY pfnDbgRequestNotify, IMG_UINT32 ui32RequesterID, PVRSRV_DBGREQ_HANDLE hDbgRequestHandle)
2282 PVRSRV_DBGREQ_NOTIFY *psNotify;
2283 PDLLIST_NODE psHead = IMG_NULL;
2285 PVRSRV_ERROR eError;
2287 if ((phNotify == IMG_NULL) || (pfnDbgRequestNotify == IMG_NULL))
2289 PVR_DPF((PVR_DBG_ERROR,"%s: Bad arguments (%p, %p,)", __FUNCTION__, phNotify, pfnDbgRequestNotify));
2290 eError = PVRSRV_ERROR_INVALID_PARAMS;
2294 psNotify = OSAllocMem(sizeof(*psNotify));
2295 if (psNotify == IMG_NULL)
2297 PVR_DPF((PVR_DBG_ERROR,"%s: Not enough memory to allocate DbgRequestNotify structure", __FUNCTION__));
2298 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
2302 /* Set-up the notify data */
2303 psNotify->hDbgRequestHandle = hDbgRequestHandle;
2304 psNotify->pfnDbgRequestNotify = pfnDbgRequestNotify;
2305 psNotify->ui32RequesterID = ui32RequesterID;
2307 /* Lock down all the lists */
2308 OSWRLockAcquireWrite(g_hDbgNotifyLock, GLOBAL_DBGNOTIFY);
2310 /* Find which list to add it to */
2311 for (i=0;i<g_psDebugTable->ui32RequestCount;i++)
2313 if (g_psDebugTable->asEntry[i].ui32RequesterID == ui32RequesterID)
2315 psHead = &g_psDebugTable->asEntry[i].sListHead;
2319 if (psHead == IMG_NULL)
2321 PVR_DPF((PVR_DBG_ERROR,"%s: Failed to find debug requester", __FUNCTION__));
2322 eError = PVRSRV_ERROR_INVALID_PARAMS;
2326 /* Add it to the list of Notify functions */
2327 dllist_add_to_tail(psHead, &psNotify->sListNode);
2329 /* Unlock the lists */
2330 OSWRLockReleaseWrite(g_hDbgNotifyLock);
2332 *phNotify = psNotify;
2337 OSWRLockReleaseWrite(g_hDbgNotifyLock);
2338 OSFreeMem(psNotify);
2345 PVRSRVUnregisterCmdCompleteNotify
2347 PVRSRV_ERROR PVRSRVUnregisterDbgRequestNotify(IMG_HANDLE hNotify)
2349 PVRSRV_DBGREQ_NOTIFY *psNotify = (PVRSRV_DBGREQ_NOTIFY*) hNotify;
2351 if (psNotify == IMG_NULL)
2353 PVR_DPF((PVR_DBG_ERROR,"%s: Bad arguments (%p)", __FUNCTION__, hNotify));
2354 return PVRSRV_ERROR_INVALID_PARAMS;
2357 /* remove the node from the list */
2358 OSWRLockAcquireWrite(g_hDbgNotifyLock, GLOBAL_DBGNOTIFY);
2359 dllist_remove_node(&psNotify->sListNode);
2360 OSWRLockReleaseWrite(g_hDbgNotifyLock);
2362 /* free the notify structure that holds the node */
2363 OSFreeMem(psNotify);
2369 static PVRSRV_ERROR PVRSRVRegisterDbgTable(IMG_UINT32 *paui32Table, IMG_UINT32 ui32Length, IMG_PVOID *phTable)
2372 if (g_psDebugTable != IMG_NULL)
2374 return PVRSRV_ERROR_DBGTABLE_ALREADY_REGISTERED;
2377 g_psDebugTable = OSAllocMem(sizeof(DEBUG_REQUEST_TABLE) + (sizeof(DEBUG_REQUEST_ENTRY) * (ui32Length-1)));
2378 if (!g_psDebugTable)
2380 return PVRSRV_ERROR_OUT_OF_MEMORY;
2383 g_psDebugTable->ui32RequestCount = ui32Length;
2385 /* Init the list heads */
2386 for (i=0;i<ui32Length;i++)
2388 g_psDebugTable->asEntry[i].ui32RequesterID = paui32Table[i];
2389 dllist_init(&g_psDebugTable->asEntry[i].sListHead);
2392 *phTable = g_psDebugTable;
2396 static IMG_VOID PVRSRVUnregisterDbgTable(IMG_PVOID hTable)
2400 PVR_ASSERT(hTable == g_psDebugTable);
2402 for (i=0;i<g_psDebugTable->ui32RequestCount;i++)
2404 if (!dllist_is_empty(&g_psDebugTable->asEntry[i].sListHead))
2406 PVR_DPF((PVR_DBG_ERROR, "PVRSRVUnregisterDbgTable: Found registered callback(s) on %d", i));
2409 OSFREEMEM(g_psDebugTable);
2410 g_psDebugTable = IMG_NULL;
2413 PVRSRV_ERROR AcquireGlobalEventObjectServer(IMG_HANDLE *phGlobalEventObject)
2415 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
2417 *phGlobalEventObject = psPVRSRVData->hGlobalEventObject;
2422 PVRSRV_ERROR ReleaseGlobalEventObjectServer(IMG_HANDLE hGlobalEventObject)
2424 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
2426 PVR_ASSERT(psPVRSRVData->hGlobalEventObject == hGlobalEventObject);
2431 PVRSRV_ERROR GetBIFTilingHeapXStride(IMG_UINT32 uiHeapNum, IMG_UINT32 *puiXStride)
2433 IMG_UINT32 uiMaxHeaps;
2435 PVR_ASSERT(puiXStride != IMG_NULL);
2437 GetNumBifTilingHeapConfigs(&uiMaxHeaps);
2439 if(uiHeapNum < 1 || uiHeapNum > uiMaxHeaps) {
2440 return PVRSRV_ERROR_INVALID_PARAMS;
2443 *puiXStride = gpsSysConfig->pui32BIFTilingHeapConfigs[uiHeapNum - 1];
2448 PVRSRV_ERROR GetNumBifTilingHeapConfigs(IMG_UINT32 *puiNumHeaps)
2450 *puiNumHeaps = gpsSysConfig->ui32BIFTilingHeapCount;
2455 PVRSRVResetHWRLogsKM
2457 PVRSRV_ERROR PVRSRVResetHWRLogsKM(PVRSRV_DEVICE_NODE *psDeviceNode)
2459 PVR_LOG(("User requested HWR logs reset"));
2461 if(psDeviceNode && psDeviceNode->pfnResetHWRLogs)
2463 return psDeviceNode->pfnResetHWRLogs(psDeviceNode);
2466 return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
2469 /*****************************************************************************
2470 End of file (pvrsrv.c)
2471 *****************************************************************************/