summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'sgx_km/eurasia_km/services4/srvkm/common/pvrsrv.c')
-rw-r--r--sgx_km/eurasia_km/services4/srvkm/common/pvrsrv.c1909
1 files changed, 1909 insertions, 0 deletions
diff --git a/sgx_km/eurasia_km/services4/srvkm/common/pvrsrv.c b/sgx_km/eurasia_km/services4/srvkm/common/pvrsrv.c
new file mode 100644
index 0000000..e823db4
--- /dev/null
+++ b/sgx_km/eurasia_km/services4/srvkm/common/pvrsrv.c
@@ -0,0 +1,1909 @@
1/*************************************************************************/ /*!
2@Title core services functions
3@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
4@Description Main APIs for core services functions
5@License Dual MIT/GPLv2
6
7The contents of this file are subject to the MIT license as set out below.
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19Alternatively, the contents of this file may be used under the terms of
20the GNU General Public License Version 2 ("GPL") in which case the provisions
21of GPL are applicable instead of those above.
22
23If you wish to allow use of your version of this file only under the terms of
24GPL, and not to allow others to use your version of this file under the terms
25of the MIT license, indicate your decision by deleting the provisions above
26and replace them with the notice and other provisions required by GPL as set
27out in the file called "GPL-COPYING" included in this distribution. If you do
28not delete the provisions above, a recipient may use your version of this file
29under the terms of either the MIT license or GPL.
30
31This License is also included in this distribution in the file called
32"MIT-COPYING".
33
34EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
35PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
36BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
38COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
39IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
40CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41*/ /**************************************************************************/
42
43#include "services_headers.h"
44#include "buffer_manager.h"
45#include "pvr_bridge_km.h"
46#include "handle.h"
47#include "perproc.h"
48#include "pdump_km.h"
49#include "deviceid.h"
50#include "ra.h"
51#if defined(TTRACE)
52#include "ttrace.h"
53#endif
54#include "perfkm.h"
55#include "devicemem.h"
56
57#include "pvrversion.h"
58
59#include "lists.h"
60
61IMG_UINT32 g_ui32InitFlags;
62
63/* mark which parts of Services were initialised */
64#define INIT_DATA_ENABLE_PDUMPINIT 0x1U
65#define INIT_DATA_ENABLE_TTRACE 0x2U
66#define INIT_DATA_ENABLE_DEVMEM 0x4U
67
68/*!
69******************************************************************************
70
71 @Function AllocateDeviceID
72
73 @Description
74
75 allocates a device id from the pool of valid ids
76
77 @input psSysData : system data
78
79 @input pui32DevID : device id to return
80
81 @Return device id
82
83******************************************************************************/
84PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID)
85{
86 SYS_DEVICE_ID* psDeviceWalker;
87 SYS_DEVICE_ID* psDeviceEnd;
88
89 psDeviceWalker = &psSysData->sDeviceID[0];
90 psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
91
92 /* find a free ID */
93 while (psDeviceWalker < psDeviceEnd)
94 {
95 if (!psDeviceWalker->bInUse)
96 {
97 psDeviceWalker->bInUse = IMG_TRUE;
98 *pui32DevID = psDeviceWalker->uiID;
99 return PVRSRV_OK;
100 }
101 psDeviceWalker++;
102 }
103
104 PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!"));
105
106 /* Should never get here: sDeviceID[] may have been setup too small */
107 PVR_ASSERT(psDeviceWalker < psDeviceEnd);
108
109 return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE;
110}
111
112
113/*!
114******************************************************************************
115
116 @Function FreeDeviceID
117
118 @Description
119
120 frees a device id from the pool of valid ids
121
122 @input psSysData : system data
123
124 @input ui32DevID : device id to free
125
126 @Return device id
127
128******************************************************************************/
129PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID)
130{
131 SYS_DEVICE_ID* psDeviceWalker;
132 SYS_DEVICE_ID* psDeviceEnd;
133
134 psDeviceWalker = &psSysData->sDeviceID[0];
135 psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
136
137 /* find the ID to free */
138 while (psDeviceWalker < psDeviceEnd)
139 {
140 /* if matching id and in use, free */
141 if (
142 (psDeviceWalker->uiID == ui32DevID) &&
143 (psDeviceWalker->bInUse)
144 )
145 {
146 psDeviceWalker->bInUse = IMG_FALSE;
147 return PVRSRV_OK;
148 }
149 psDeviceWalker++;
150 }
151
152 PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!"));
153
154 /* should never get here */
155 PVR_ASSERT(psDeviceWalker < psDeviceEnd);
156
157 return PVRSRV_ERROR_INVALID_DEVICEID;
158}
159/*!
160******************************************************************************
161
162 @Function PVRSRVCompatCheckKM
163
164 @Description UM/KM ddk branch Compatibility check function
165
166 @input psUserModeDDKDetails: User mode DDK version
167
168 @output In case of incompatibility, returns PVRSRV_ERROR_DDK_VERSION_MISMATCH
169
170 @Return PVRSRV_ERROR
171
172******************************************************************************/
173IMG_VOID IMG_CALLCONV PVRSRVCompatCheckKM(PVRSRV_BRIDGE_IN_COMPAT_CHECK *psUserModeDDKDetails, PVRSRV_BRIDGE_RETURN *psRetOUT)
174{
175#if defined(SUPPORT_TI_VERSION_STRING)
176 SYS_DATA *psSysData;
177
178 SysAcquireData(&psSysData);
179#endif
180
181 if(psUserModeDDKDetails->ui32DDKVersion != ((PVRVERSION_MAJ << 16) | (PVRVERSION_MIN << 8))
182 || (psUserModeDDKDetails->ui32DDKBuild != PVRVERSION_BUILD))
183 {
184 psRetOUT->eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH;
185 PVR_LOG(("(FAIL) UM-KM DDK Mismatch UM-(%d) KM-(%d).",
186 psUserModeDDKDetails->ui32DDKBuild, PVRVERSION_BUILD));
187 }
188 else
189 {
190 psRetOUT->eError = PVRSRV_OK;
191 PVR_LOG(("UM DDK-(%d) and KM DDK-(%d) match. [ OK ]",
192 psUserModeDDKDetails->ui32DDKBuild ,PVRVERSION_BUILD));
193 }
194
195#if defined(SUPPORT_TI_VERSION_STRING)
196 /* If TI version string is supported, populate it here. This will show
197 * up in proc entry.
198 * Probably a bad place to do this. FIXME
199 */
200 memcpy(psSysData->szTIVersion, psUserModeDDKDetails->szTIVersion, 64);
201#endif
202}
203
204/*!
205******************************************************************************
206
207 @Function ReadHWReg
208
209 @Description
210
211 register access function
212
213 @input pvLinRegBaseAddr : lin addr of register block base
214
215 @input ui32Offset : byte offset from register base
216
217 @Return register value
218
219******************************************************************************/
220#ifndef ReadHWReg
221IMG_EXPORT
222IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
223{
224 return *(volatile IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset);
225}
226#endif
227
228
229/*!
230******************************************************************************
231
232 @Function WriteHWReg
233
234 @Description
235
236 register access function
237
238 @input pvLinRegBaseAddr : lin addr of register block base
239
240 @input ui32Offset : byte offset from register base
241
242 @input ui32Value : value to write to register
243
244 @Return register value : original reg. value
245
246******************************************************************************/
247#ifndef WriteHWReg
248IMG_EXPORT
249IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
250{
251 PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%p, Offset: %x, Value %x",
252 pvLinRegBaseAddr,ui32Offset,ui32Value));
253
254 *(IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset) = ui32Value;
255}
256#endif
257
258
259/*!
260******************************************************************************
261
262 @Function WriteHWRegs
263
264 @Description
265
266 register access function
267
268 @input pvLinRegBaseAddr : lin addr of register block base
269
270 @input ui32Count : register count
271
272 @input psHWRegs : address/value register list
273
274 @Return none
275
276******************************************************************************/
277#ifndef WriteHWRegs
278IMG_EXPORT
279IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs)
280{
281 while (ui32Count)
282 {
283 WriteHWReg (pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal);
284 psHWRegs++;
285 ui32Count--;
286 }
287}
288#endif
289
290/*!
291******************************************************************************
292 @Function PVRSRVEnumerateDCKM_ForEachVaCb
293
294 @Description
295
296 Enumerates the device node (if is of the same class as given).
297
298 @Input psDeviceNode - The device node to be enumerated
299 va - variable arguments list, with:
300 pui32DevCount - The device count pointer (to be increased)
301 ppui32DevID - The pointer to the device IDs pointer (to be updated and increased)
302******************************************************************************/
303static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
304{
305 IMG_UINT *pui32DevCount;
306 PVRSRV_DEVICE_IDENTIFIER **ppsDevIdList;
307
308 pui32DevCount = va_arg(va, IMG_UINT*);
309 ppsDevIdList = va_arg(va, PVRSRV_DEVICE_IDENTIFIER**);
310
311 if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT)
312 {
313 *(*ppsDevIdList) = psDeviceNode->sDevId;
314 (*ppsDevIdList)++;
315 (*pui32DevCount)++;
316 }
317}
318
319
320
321/*!
322******************************************************************************
323
324 @Function PVRSRVEnumerateDevicesKM
325
326 @Description
327 This function will enumerate all the devices supported by the
328 PowerVR services within the target system.
329 The function returns a list of the device ID strcutres stored either in
330 the services or constructed in the user mode glue component in certain
331 environments. The number of devices in the list is also returned.
332
333 In a binary layered component which does not support dynamic runtime selection,
334 the glue code should compile to return the supported devices statically,
335 e.g. multiple instances of the same device if multiple devices are supported,
336 or the target combination of MBX and display device.
337
338 In the case of an environment (for instance) where one MBX1 may connect to two
339 display devices this code would enumerate all three devices and even
340 non-dynamic MBX1 selection code should retain the facility to parse the list
341 to find the index of the MBX device
342
343 @output pui32NumDevices : On success, contains the number of devices present
344 in the system
345
346 @output psDevIdList : Pointer to called supplied buffer to receive the
347 list of PVRSRV_DEVICE_IDENTIFIER
348
349 @return PVRSRV_ERROR : PVRSRV_NO_ERROR
350
351******************************************************************************/
352IMG_EXPORT
353PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
354 PVRSRV_DEVICE_IDENTIFIER *psDevIdList)
355{
356 SYS_DATA *psSysData;
357/* PVRSRV_DEVICE_NODE *psDeviceNode; */
358 IMG_UINT32 i;
359
360 if (!pui32NumDevices || !psDevIdList)
361 {
362 PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params"));
363 return PVRSRV_ERROR_INVALID_PARAMS;
364 }
365
366 SysAcquireData(&psSysData);
367
368 /*
369 setup input buffer to be `empty'
370 */
371 for (i=0; i<PVRSRV_MAX_DEVICES; i++)
372 {
373 psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN;
374 }
375
376 /* and zero device count */
377 *pui32NumDevices = 0;
378
379 /*
380 Search through the device list for services managed devices
381 return id info for each device and the number of devices
382 available
383 */
384 List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
385 &PVRSRVEnumerateDevicesKM_ForEachVaCb,
386 pui32NumDevices,
387 &psDevIdList);
388
389
390 return PVRSRV_OK;
391}
392
393
394/*!
395******************************************************************************
396
397 @Function PVRSRVInit
398
399 @Description Initialise services
400
401 @Input psSysData : sysdata structure
402
403 @Return PVRSRV_ERROR :
404
405******************************************************************************/
406PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData)
407{
408 PVRSRV_ERROR eError;
409
410 /* Initialise Resource Manager */
411 eError = ResManInit();
412 if (eError != PVRSRV_OK)
413 {
414 goto Error;
415 }
416
417 eError = PVRSRVPerProcessDataInit();
418 if(eError != PVRSRV_OK)
419 {
420 goto Error;
421 }
422
423 /* Initialise handles */
424 eError = PVRSRVHandleInit();
425 if(eError != PVRSRV_OK)
426 {
427 goto Error;
428 }
429
430 /* Initialise Power Manager Lock */
431 eError = OSCreateResource(&psSysData->sPowerStateChangeResource);
432 if (eError != PVRSRV_OK)
433 {
434 goto Error;
435 }
436
437 /* Initialise system power state */
438 psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0;
439 psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
440
441 /* Create an event object */
442 if((eError = OSAllocMem( PVRSRV_PAGEABLE_SELECT,
443 sizeof(PVRSRV_EVENTOBJECT) ,
444 (IMG_VOID **)&psSysData->psGlobalEventObject, 0,
445 "Event Object")) != PVRSRV_OK)
446 {
447
448 goto Error;
449 }
450
451 if((eError = OSEventObjectCreateKM("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject)) != PVRSRV_OK)
452 {
453 goto Error;
454 }
455
456 /* Store OS high res timer fallbacks, the system is free to overide these */
457 psSysData->pfnHighResTimerCreate = OSFuncHighResTimerCreate;
458 psSysData->pfnHighResTimerGetus = OSFuncHighResTimerGetus;
459 psSysData->pfnHighResTimerDestroy = OSFuncHighResTimerDestroy;
460
461#if defined(TTRACE)
462 eError = PVRSRVTimeTraceInit();
463 if (eError != PVRSRV_OK)
464 goto Error;
465 g_ui32InitFlags |= INIT_DATA_ENABLE_TTRACE;
466#endif
467
468#if defined(PDUMP)
469 /* Initialise pdump */
470 PDUMPINIT();
471 g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT;
472#endif
473
474#if defined(SUPPORT_ION) || defined(SUPPORT_DMABUF)
475 eError = PVRSRVInitDeviceMem();
476 if (eError != PVRSRV_OK)
477 goto Error;
478 g_ui32InitFlags |= INIT_DATA_ENABLE_DEVMEM;
479#endif
480
481 PERFINIT();
482 return eError;
483
484Error:
485 PVRSRVDeInit(psSysData);
486 return eError;
487}
488
489
490
491/*!
492******************************************************************************
493
494 @Function PVRSRVDeInit
495
496 @Description De-Initialise services
497
498 @Input psSysData : sysdata structure
499
500 @Return PVRSRV_ERROR :
501
502******************************************************************************/
503IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData)
504{
505 PVRSRV_ERROR eError;
506
507 PVR_UNREFERENCED_PARAMETER(psSysData);
508
509 if (psSysData == IMG_NULL)
510 {
511 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed - invalid param"));
512 return;
513 }
514
515 PERFDEINIT();
516
517
518#if defined(SUPPORT_ION) || defined(SUPPORT_DMABUF)
519 if ((g_ui32InitFlags & INIT_DATA_ENABLE_DEVMEM) > 0)
520 {
521 PVRSRVDeInitDeviceMem();
522 }
523#endif
524
525#if defined(MEM_TRACK_INFO_DEBUG)
526 /* Free the list of memory operations */
527 PVRSRVFreeMemOps();
528#endif
529
530#if defined(TTRACE)
531 /* deinitialise ttrace */
532 if ((g_ui32InitFlags & INIT_DATA_ENABLE_TTRACE) > 0)
533 {
534 PVRSRVTimeTraceDeinit();
535 }
536#endif
537
538#if defined(PDUMP)
539 /* deinitialise pdump */
540 if( (g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0)
541 {
542 PDUMPDEINIT();
543 }
544#endif
545
546 /* destroy event object */
547 if(psSysData->psGlobalEventObject)
548 {
549 OSEventObjectDestroyKM(psSysData->psGlobalEventObject);
550 OSFreeMem( PVRSRV_PAGEABLE_SELECT,
551 sizeof(PVRSRV_EVENTOBJECT),
552 psSysData->psGlobalEventObject,
553 0);
554 psSysData->psGlobalEventObject = IMG_NULL;
555 }
556
557 eError = PVRSRVHandleDeInit();
558 if (eError != PVRSRV_OK)
559 {
560 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed"));
561 }
562
563 eError = PVRSRVPerProcessDataDeInit();
564 if (eError != PVRSRV_OK)
565 {
566 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVPerProcessDataDeInit failed"));
567 }
568
569 ResManDeInit();
570}
571
572
573/*!
574******************************************************************************
575
576 @Function PVRSRVRegisterDevice
577
578 @Description
579
580 registers a device with the system
581
582 @Input psSysData : sysdata structure
583
584 @Input pfnRegisterDevice : device registration function
585
586 @Input ui32SOCInterruptBit : SoC interrupt bit for this device
587
588 @Output pui32DeviceIndex : unique device key (for case of multiple identical devices)
589
590 @Return PVRSRV_ERROR :
591
592******************************************************************************/
593PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData,
594 PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*),
595 IMG_UINT32 ui32SOCInterruptBit,
596 IMG_UINT32 *pui32DeviceIndex)
597{
598 PVRSRV_ERROR eError;
599 PVRSRV_DEVICE_NODE *psDeviceNode;
600
601 /* Allocate device node */
602 if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
603 sizeof(PVRSRV_DEVICE_NODE),
604 (IMG_VOID **)&psDeviceNode, IMG_NULL,
605 "Device Node") != PVRSRV_OK)
606 {
607 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode"));
608 return (PVRSRV_ERROR_OUT_OF_MEMORY);
609 }
610 OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
611
612 eError = pfnRegisterDevice(psDeviceNode);
613 if (eError != PVRSRV_OK)
614 {
615 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
616 sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
617 /*not nulling pointer, out of scope*/
618 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device"));
619 return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED);
620 }
621
622 /*
623 make the refcount 1 and test on this to initialise device
624 at acquiredevinfo. On release if refcount is 1, deinitialise
625 and when refcount is 0 (sysdata de-alloc) deallocate the device
626 structures
627 */
628 psDeviceNode->ui32RefCount = 1;
629 psDeviceNode->psSysData = psSysData;
630 psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit;
631
632 /* all devices need a unique identifier */
633 AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
634
635 /* and finally insert the device into the dev-list */
636 List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
637
638 /* and copy back index */
639 *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
640
641 return PVRSRV_OK;
642}
643
644
645/*!
646******************************************************************************
647
648 @Function PVRSRVInitialiseDevice
649
650 @Description
651
652 initialises device by index
653
654 @Input ui32DevIndex : Index to the required device
655
656 @Return PVRSRV_ERROR :
657
658******************************************************************************/
659PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex)
660{
661 PVRSRV_DEVICE_NODE *psDeviceNode;
662 SYS_DATA *psSysData;
663 PVRSRV_ERROR eError;
664
665 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice"));
666
667 SysAcquireData(&psSysData);
668
669 /* Find device in the list */
670 psDeviceNode = (PVRSRV_DEVICE_NODE*)
671 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
672 &MatchDeviceKM_AnyVaCb,
673 ui32DevIndex,
674 IMG_TRUE);
675 if(!psDeviceNode)
676 {
677 /* Devinfo not in the list */
678 PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present"));
679 return PVRSRV_ERROR_INIT_FAILURE;
680 }
681/*
682FoundDevice:
683*/
684
685 PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
686
687 /*
688 Create the device's resource manager context.
689 */
690 eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext);
691 if (eError != PVRSRV_OK)
692 {
693 PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call"));
694 return eError;
695 }
696
697 /* Initialise the device */
698 if(psDeviceNode->pfnInitDevice != IMG_NULL)
699 {
700 eError = psDeviceNode->pfnInitDevice(psDeviceNode);
701 if (eError != PVRSRV_OK)
702 {
703 PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call"));
704 return eError;
705 }
706 }
707
708 return PVRSRV_OK;
709}
710
711
712static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
713{
714 PVRSRV_ERROR eError;
715
716 eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
717 if (eError != PVRSRV_OK)
718 {
719 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVPowerLock call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
720 return eError;
721 }
722
723 eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
724 PVRSRV_DEV_POWER_STATE_DEFAULT);
725 PVRSRVPowerUnlock(KERNEL_ID);
726 if (eError != PVRSRV_OK)
727 {
728 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
729 }
730 return eError;
731}
732
733/*wraps the PVRSRVDevInitCompatCheck call and prints a debugging message if failed*/
734static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
735{
736 PVRSRV_ERROR eError;
737 eError = PVRSRVDevInitCompatCheck(psDeviceNode);
738 if (eError != PVRSRV_OK)
739 {
740 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
741 }
742 return eError;
743}
744
745
746/*!
747******************************************************************************
748
749 @Function PVRSRVFinaliseSystem
750
751 @Description
752
753 Final part of system initialisation.
754
755 @Input ui32DevIndex : Index to the required device
756
757 @Return PVRSRV_ERROR :
758
759******************************************************************************/
760PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful)
761{
762/* PVRSRV_DEVICE_NODE *psDeviceNode;*/
763 SYS_DATA *psSysData;
764 PVRSRV_ERROR eError;
765
766 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem"));
767
768 SysAcquireData(&psSysData);
769
770 if (bInitSuccessful)
771 {
772 eError = SysFinalise();
773 if (eError != PVRSRV_OK)
774 {
775 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError));
776 return eError;
777 }
778
779 /* Place all devices into their default power state. */
780 eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
781 &PVRSRVFinaliseSystem_SetPowerState_AnyCb);
782 if (eError != PVRSRV_OK)
783 {
784 return eError;
785 }
786
787 /* Verify microkernel compatibility for devices */
788 eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
789 &PVRSRVFinaliseSystem_CompatCheck_AnyCb);
790 if (eError != PVRSRV_OK)
791 {
792 return eError;
793 }
794 }
795
796 /* Some platforms call this too early in the boot phase. */
797 PDUMPENDINITPHASE();
798
799 return PVRSRV_OK;
800}
801
802
803PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
804{
805 /* Only check devices which specify a compatibility check callback */
806 if (psDeviceNode->pfnInitDeviceCompatCheck)
807 return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode);
808 else
809 return PVRSRV_OK;
810}
811
812/*!
813******************************************************************************
814
815 @Function PVRSRVAcquireDeviceDataKM
816
817 @Description
818
819 Matchs a device given a device type and a device index.
820
821 @input psDeviceNode :The device node to be matched.
822
823 @Input va : Variable argument list with:
824 eDeviceType : Required device type. If type is unknown use ui32DevIndex
825 to locate device data
826
827 ui32DevIndex : Index to the required device obtained from the
828 PVRSRVEnumerateDevice function
829
830 @Return PVRSRV_ERROR :
831
832******************************************************************************/
833static IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
834{
835 PVRSRV_DEVICE_TYPE eDeviceType;
836 IMG_UINT32 ui32DevIndex;
837
838 eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE);
839 ui32DevIndex = va_arg(va, IMG_UINT32);
840
841 if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN &&
842 psDeviceNode->sDevId.eDeviceType == eDeviceType) ||
843 (eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN &&
844 psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex))
845 {
846 return psDeviceNode;
847 }
848 else
849 {
850 return IMG_NULL;
851 }
852}
853
854/*!
855******************************************************************************
856
857 @Function PVRSRVAcquireDeviceDataKM
858
859 @Description
860
861 Returns device information
862
863 @Input ui32DevIndex : Index to the required device obtained from the
864 PVRSRVEnumerateDevice function
865
866 @Input eDeviceType : Required device type. If type is unknown use ui32DevIndex
867 to locate device data
868
869 @Output *phDevCookie : Dev Cookie
870
871
872 @Return PVRSRV_ERROR :
873
874******************************************************************************/
875IMG_EXPORT
876PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex,
877 PVRSRV_DEVICE_TYPE eDeviceType,
878 IMG_HANDLE *phDevCookie)
879{
880 PVRSRV_DEVICE_NODE *psDeviceNode;
881 SYS_DATA *psSysData;
882
883 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM"));
884
885 SysAcquireData(&psSysData);
886
887 /* Find device in the list */
888 psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
889 &PVRSRVAcquireDeviceDataKM_Match_AnyVaCb,
890 eDeviceType,
891 ui32DevIndex);
892
893
894 if (!psDeviceNode)
895 {
896 /* device can't be found in the list so it isn't in the system */
897 PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present"));
898 return PVRSRV_ERROR_INIT_FAILURE;
899 }
900
901/*FoundDevice:*/
902
903 PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
904
905 /* return the dev cookie? */
906 if (phDevCookie)
907 {
908 *phDevCookie = (IMG_HANDLE)psDeviceNode;
909 }
910
911 return PVRSRV_OK;
912}
913
914
915/*!
916******************************************************************************
917
918 @Function PVRSRVDeinitialiseDevice
919
920 @Description
921
922 This De-inits device
923
924 @Input ui32DevIndex : Index to the required device
925
926 @Return PVRSRV_ERROR :
927
928******************************************************************************/
929PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex)
930{
931 PVRSRV_DEVICE_NODE *psDeviceNode;
932 SYS_DATA *psSysData;
933 PVRSRV_ERROR eError;
934
935 SysAcquireData(&psSysData);
936
937 psDeviceNode = (PVRSRV_DEVICE_NODE*)
938 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
939 &MatchDeviceKM_AnyVaCb,
940 ui32DevIndex,
941 IMG_TRUE);
942
943 if (!psDeviceNode)
944 {
945 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex));
946 return PVRSRV_ERROR_DEVICEID_NOT_FOUND;
947 }
948
949 eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
950 if (eError != PVRSRV_OK)
951 {
952 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVPowerLock call"));
953 return eError;
954 }
955
956 /*
957 Power down the device if necessary.
958 */
959 eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex,
960 PVRSRV_DEV_POWER_STATE_OFF);
961 PVRSRVPowerUnlock(KERNEL_ID);
962 if (eError != PVRSRV_OK)
963 {
964 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call"));
965 return eError;
966 }
967
968 /*
969 Free the dissociated device memory.
970 */
971 eError = ResManFreeResByCriteria(psDeviceNode->hResManContext,
972 RESMAN_CRITERIA_RESTYPE,
973 RESMAN_TYPE_DEVICEMEM_ALLOCATION,
974 IMG_NULL, 0);
975 if (eError != PVRSRV_OK)
976 {
977 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call"));
978 return eError;
979 }
980
981 /*
982 De-init the device.
983 */
984 if(psDeviceNode->pfnDeInitDevice != IMG_NULL)
985 {
986 eError = psDeviceNode->pfnDeInitDevice(psDeviceNode);
987 if (eError != PVRSRV_OK)
988 {
989 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call"));
990 return eError;
991 }
992 }
993
994 /*
995 Close the device's resource manager context.
996 */
997 PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE);
998 psDeviceNode->hResManContext = IMG_NULL;
999
1000 /* remove node from list */
1001 List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
1002
1003 /* deallocate id and memory */
1004 (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
1005 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
1006 sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
1007 /*not nulling pointer, out of scope*/
1008
1009 return (PVRSRV_OK);
1010}
1011
1012
1013IMG_EXPORT
1014PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr,
1015 IMG_UINT32 ui32Value,
1016 IMG_UINT32 ui32Mask,
1017 IMG_UINT32 ui32Timeoutus,
1018 IMG_UINT32 ui32PollPeriodus,
1019 IMG_BOOL bAllowPreemption)
1020{
1021#if defined (EMULATOR)
1022 {
1023 PVR_UNREFERENCED_PARAMETER(bAllowPreemption);
1024 #if !defined(__linux__)
1025 PVR_UNREFERENCED_PARAMETER(ui32PollPeriodus);
1026 #endif
1027
1028 /* For the Emulator we want the system to stop when a lock-up is detected so the state can be analysed.
1029 * Also the Emulator is much slower than real silicon so timeouts are not valid.
1030 */
1031 if((*pui32LinMemAddr & ui32Mask) == ui32Value)
1032 {
1033 return PVRSRV_OK;
1034 }
1035
1036 do
1037 {
1038 #if defined(__linux__)
1039 OSWaitus(ui32PollPeriodus);
1040 #else
1041 OSReleaseThreadQuanta();
1042 #endif
1043
1044 if((*pui32LinMemAddr & ui32Mask) == ui32Value)
1045 {
1046 return PVRSRV_OK;
1047 }
1048
1049 } while (ui32Timeoutus); /* Endless loop only for the Emulator */
1050 }
1051#else
1052 {
1053 IMG_UINT32 ui32ActualValue = 0xFFFFFFFFU; /* Initialiser only required to prevent incorrect warning */
1054
1055 if (bAllowPreemption)
1056 {
1057 PVR_ASSERT(ui32PollPeriodus >= 1000);
1058 }
1059
1060 ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
1061 if(ui32ActualValue == ui32Value)
1062 {
1063 return PVRSRV_OK;
1064 }
1065
1066 /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */
1067 LOOP_UNTIL_TIMEOUT(ui32Timeoutus)
1068 {
1069 if (bAllowPreemption)
1070 {
1071 OSSleepms(ui32PollPeriodus / 1000);
1072 }
1073 else
1074 {
1075 OSWaitus(ui32PollPeriodus);
1076 }
1077
1078 ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
1079 if(ui32ActualValue == ui32Value)
1080 {
1081 return PVRSRV_OK;
1082 }
1083
1084 } END_LOOP_UNTIL_TIMEOUT();
1085
1086 PVR_DPF((PVR_DBG_ERROR,"PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).",
1087 ui32Value, ui32ActualValue, ui32Mask));
1088 }
1089#endif /* #if defined (EMULATOR) */
1090
1091 return PVRSRV_ERROR_TIMEOUT;
1092}
1093
1094
1095/*Level 3 of the loop nesting*/
1096static IMG_VOID PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
1097{
1098 IMG_CHAR **ppszStr;
1099 IMG_UINT32 *pui32StrLen;
1100 IMG_UINT32 ui32Mode;
1101 PVRSRV_ERROR (*pfnGetStats)(RA_ARENA *, IMG_CHAR **, IMG_UINT32 *);
1102
1103 ppszStr = va_arg(va, IMG_CHAR**);
1104 pui32StrLen = va_arg(va, IMG_UINT32*);
1105 ui32Mode = va_arg(va, IMG_UINT32);
1106
1107 /* Would be better to pass fn pointer in the variable args list
1108 * but MS C compiler complains with error C2066: In ANSI C,
1109 * it is not legal to cast between a function pointer and a data pointer.
1110 */
1111 switch(ui32Mode)
1112 {
1113 case PVRSRV_MISC_INFO_MEMSTATS_PRESENT:
1114 pfnGetStats = &RA_GetStats;
1115 break;
1116 case PVRSRV_MISC_INFO_FREEMEM_PRESENT:
1117 pfnGetStats = &RA_GetStatsFreeMem;
1118 break;
1119 default:
1120 return;
1121 }
1122
1123 if(psBMHeap->pImportArena)
1124 {
1125 pfnGetStats(psBMHeap->pImportArena,
1126 ppszStr,
1127 pui32StrLen);
1128 }
1129
1130 if(psBMHeap->pVMArena)
1131 {
1132 pfnGetStats(psBMHeap->pVMArena,
1133 ppszStr,
1134 pui32StrLen);
1135 }
1136}
1137
1138/*Level 2 of the loop nesting*/
1139static PVRSRV_ERROR PVRSRVGetMiscInfoKM_BMContext_AnyVaCb(BM_CONTEXT *psBMContext, va_list va)
1140{
1141
1142 IMG_UINT32 *pui32StrLen;
1143 IMG_INT32 *pi32Count;
1144 IMG_CHAR **ppszStr;
1145 IMG_UINT32 ui32Mode;
1146
1147 pui32StrLen = va_arg(va, IMG_UINT32*);
1148 pi32Count = va_arg(va, IMG_INT32*);
1149 ppszStr = va_arg(va, IMG_CHAR**);
1150 ui32Mode = va_arg(va, IMG_UINT32);
1151
1152 CHECK_SPACE(*pui32StrLen);
1153 *pi32Count = OSSNPrintf(*ppszStr, 100, "\nApplication Context (hDevMemContext) %p:\n",
1154 (IMG_HANDLE)psBMContext);
1155 UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
1156
1157 List_BM_HEAP_ForEach_va(psBMContext->psBMHeap,
1158 &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
1159 ppszStr,
1160 pui32StrLen,
1161 ui32Mode);
1162 return PVRSRV_OK;
1163}
1164
1165
1166/*level 1 of the loop nesting*/
1167static PVRSRV_ERROR PVRSRVGetMiscInfoKM_Device_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
1168{
1169 IMG_UINT32 *pui32StrLen;
1170 IMG_INT32 *pi32Count;
1171 IMG_CHAR **ppszStr;
1172 IMG_UINT32 ui32Mode;
1173
1174 pui32StrLen = va_arg(va, IMG_UINT32*);
1175 pi32Count = va_arg(va, IMG_INT32*);
1176 ppszStr = va_arg(va, IMG_CHAR**);
1177 ui32Mode = va_arg(va, IMG_UINT32);
1178
1179 CHECK_SPACE(*pui32StrLen);
1180 *pi32Count = OSSNPrintf(*ppszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType);
1181 UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
1182
1183 /* kernel context: */
1184 if(psDeviceNode->sDevMemoryInfo.pBMKernelContext)
1185 {
1186 CHECK_SPACE(*pui32StrLen);
1187 *pi32Count = OSSNPrintf(*ppszStr, 100, "\nKernel Context:\n");
1188 UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
1189
1190 List_BM_HEAP_ForEach_va(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap,
1191 &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
1192 ppszStr,
1193 pui32StrLen,
1194 ui32Mode);
1195 }
1196
1197 /* double loop app contexts:heaps */
1198 return List_BM_CONTEXT_PVRSRV_ERROR_Any_va(psDeviceNode->sDevMemoryInfo.pBMContext,
1199 &PVRSRVGetMiscInfoKM_BMContext_AnyVaCb,
1200 pui32StrLen,
1201 pi32Count,
1202 ppszStr,
1203 ui32Mode);
1204}
1205
1206
1207/*!
1208******************************************************************************
1209
1210 @Function PVRSRVGetMiscInfoKM
1211
1212 @Description
1213 Retrieves misc. info.
1214
1215 @Output PVRSRV_MISC_INFO
1216
1217 @Return PVRSRV_ERROR :
1218
1219******************************************************************************/
1220IMG_EXPORT
1221PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo)
1222{
1223 SYS_DATA *psSysData;
1224
1225 if(!psMiscInfo)
1226 {
1227 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters"));
1228 return PVRSRV_ERROR_INVALID_PARAMS;
1229 }
1230
1231 psMiscInfo->ui32StatePresent = 0;
1232
1233 /* do a basic check for uninitialised request flag */
1234 if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT
1235 |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT
1236 |PVRSRV_MISC_INFO_MEMSTATS_PRESENT
1237 |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT
1238 |PVRSRV_MISC_INFO_DDKVERSION_PRESENT
1239 |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT
1240 |PVRSRV_MISC_INFO_RESET_PRESENT
1241 |PVRSRV_MISC_INFO_FREEMEM_PRESENT
1242 |PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT
1243 |PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT
1244 |PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT))
1245 {
1246 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags"));
1247 return PVRSRV_ERROR_INVALID_PARAMS;
1248 }
1249
1250 SysAcquireData(&psSysData);
1251
1252 /* return SOC Timer registers */
1253 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) &&
1254 (psSysData->pvSOCTimerRegisterKM != IMG_NULL))
1255 {
1256 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT;
1257 psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM;
1258 psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle;
1259 }
1260 else
1261 {
1262 psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL;
1263 psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL;
1264 }
1265
1266 /* return SOC Clock Gating registers */
1267 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) &&
1268 (psSysData->pvSOCClockGateRegsBase != IMG_NULL))
1269 {
1270 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT;
1271 psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase;
1272 psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize;
1273 }
1274
1275 /* memory stats */
1276 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) &&
1277 (psMiscInfo->pszMemoryStr != IMG_NULL))
1278 {
1279 RA_ARENA **ppArena;
1280/* BM_HEAP *psBMHeap;
1281 BM_CONTEXT *psBMContext;
1282 PVRSRV_DEVICE_NODE *psDeviceNode;*/
1283 IMG_CHAR *pszStr;
1284 IMG_UINT32 ui32StrLen;
1285 IMG_INT32 i32Count;
1286
1287 pszStr = psMiscInfo->pszMemoryStr;
1288 ui32StrLen = psMiscInfo->ui32MemoryStrLen;
1289
1290 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT;
1291
1292 /* Local backing stores */
1293 ppArena = &psSysData->apsLocalDevMemArena[0];
1294 while(*ppArena)
1295 {
1296 CHECK_SPACE(ui32StrLen);
1297 i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n");
1298 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1299
1300 RA_GetStats(*ppArena,
1301 &pszStr,
1302 &ui32StrLen);
1303 /* advance through the array */
1304 ppArena++;
1305 }
1306
1307 /* per device */
1308/* psDeviceNode = psSysData->psDeviceNodeList;*/
1309
1310 /*triple loop; devices:contexts:heaps*/
1311 List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
1312 &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
1313 &ui32StrLen,
1314 &i32Count,
1315 &pszStr,
1316 PVRSRV_MISC_INFO_MEMSTATS_PRESENT);
1317
1318 /* attach a new line and string terminate */
1319 i32Count = OSSNPrintf(pszStr, 100, "\n");
1320 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1321 }
1322
1323 /* Lean version of mem stats: only show free mem on each RA */
1324 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0)
1325 && psMiscInfo->pszMemoryStr)
1326 {
1327 IMG_CHAR *pszStr;
1328 IMG_UINT32 ui32StrLen;
1329 IMG_INT32 i32Count;
1330
1331 pszStr = psMiscInfo->pszMemoryStr;
1332 ui32StrLen = psMiscInfo->ui32MemoryStrLen;
1333
1334 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT;
1335
1336 /* triple loop over devices:contexts:heaps */
1337 List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
1338 &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
1339 &ui32StrLen,
1340 &i32Count,
1341 &pszStr,
1342 PVRSRV_MISC_INFO_FREEMEM_PRESENT);
1343
1344 i32Count = OSSNPrintf(pszStr, 100, "\n");
1345 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1346 }
1347
1348 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) &&
1349 (psSysData->psGlobalEventObject != IMG_NULL))
1350 {
1351 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT;
1352 psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject;
1353 }
1354
1355 /* DDK version and memstats not supported in same call to GetMiscInfo */
1356
1357 if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL)
1358 && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL)
1359 && (psMiscInfo->pszMemoryStr != IMG_NULL))
1360 {
1361 IMG_CHAR *pszStr;
1362 IMG_UINT32 ui32StrLen;
1363 IMG_UINT32 ui32LenStrPerNum = 12; /* string length per UI32: 10 digits + '.' + '\0' = 12 bytes */
1364 IMG_INT32 i32Count;
1365 IMG_INT i;
1366 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT;
1367
1368 /* construct DDK string */
1369 psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ;
1370 psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN;
1371 psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BUILD_HI;
1372 psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD_LO;
1373
1374 pszStr = psMiscInfo->pszMemoryStr;
1375 ui32StrLen = psMiscInfo->ui32MemoryStrLen;
1376
1377 for (i=0; i<4; i++)
1378 {
1379 if (ui32StrLen < ui32LenStrPerNum)
1380 {
1381 return PVRSRV_ERROR_INVALID_PARAMS;
1382 }
1383
1384 i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]);
1385 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1386 if (i != 3)
1387 {
1388 i32Count = OSSNPrintf(pszStr, 2, ".");
1389 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1390 }
1391 }
1392 }
1393
1394 if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL)
1395 {
1396 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT;
1397
1398 if(psMiscInfo->sCacheOpCtl.bDeferOp)
1399 {
1400 /* For now, assume deferred ops are "full" cache ops,
1401 * and we don't need (or expect) a meminfo.
1402 */
1403 psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType;
1404 }
1405 else
1406 {
1407 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
1408 PVRSRV_PER_PROCESS_DATA *psPerProc;
1409
1410 if(!psMiscInfo->sCacheOpCtl.u.hKernelMemInfo)
1411 {
1412 PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
1413 "Ignoring non-deferred cache op with no meminfo"));
1414 return PVRSRV_ERROR_INVALID_PARAMS;
1415 }
1416
1417 if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE)
1418 {
1419 PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
1420 "Deferred cache op is pending. It is unlikely you want "
1421 "to combine deferred cache ops with immediate ones"));
1422 }
1423
1424 psPerProc = PVRSRVFindPerProcessData();
1425
1426 if(PVRSRVLookupHandle(psPerProc->psHandleBase,
1427 (IMG_PVOID *)&psKernelMemInfo,
1428 psMiscInfo->sCacheOpCtl.u.hKernelMemInfo,
1429 PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
1430 {
1431 PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: "
1432 "Can't find kernel meminfo"));
1433 return PVRSRV_ERROR_INVALID_PARAMS;
1434 }
1435
1436 if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
1437 {
1438 if(psMiscInfo->sCacheOpCtl.ui32Length!=0)
1439 {
1440 if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
1441 0,
1442 psMiscInfo->sCacheOpCtl.pvBaseVAddr,
1443 psMiscInfo->sCacheOpCtl.ui32Length))
1444 {
1445 return PVRSRV_ERROR_CACHEOP_FAILED;
1446 }
1447 }
1448 }
1449 else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
1450 {
1451 if(psMiscInfo->sCacheOpCtl.ui32Length!=0)
1452 {
1453 if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
1454 0,
1455 psMiscInfo->sCacheOpCtl.pvBaseVAddr,
1456 psMiscInfo->sCacheOpCtl.ui32Length))
1457 {
1458 return PVRSRV_ERROR_CACHEOP_FAILED;
1459 }
1460 }
1461 }
1462 }
1463 }
1464
1465 if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT) != 0UL)
1466 {
1467 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
1468 PVRSRV_PER_PROCESS_DATA *psPerProc;
1469
1470 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT;
1471
1472 psPerProc = PVRSRVFindPerProcessData();
1473
1474 if(PVRSRVLookupHandle(psPerProc->psHandleBase,
1475 (IMG_PVOID *)&psKernelMemInfo,
1476 psMiscInfo->sGetRefCountCtl.u.hKernelMemInfo,
1477 PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
1478 {
1479 PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: "
1480 "Can't find kernel meminfo"));
1481 return PVRSRV_ERROR_INVALID_PARAMS;
1482 }
1483
1484 psMiscInfo->sGetRefCountCtl.ui32RefCount = psKernelMemInfo->ui32RefCount;
1485 }
1486
1487 if ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT) != 0UL)
1488 {
1489 psMiscInfo->ui32PageSize = HOST_PAGESIZE();
1490 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT;
1491 }
1492
1493#if defined(PVRSRV_RESET_ON_HWTIMEOUT)
1494 if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL)
1495 {
1496 PVR_LOG(("User requested OS reset"));
1497 OSPanic();
1498 }
1499#endif /* #if defined(PVRSRV_RESET_ON_HWTIMEOUT) */
1500
1501#if defined(SUPPORT_PVRSRV_DEVICE_CLASS)
1502 if ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT) != 0UL)
1503 {
1504 PVRSRVProcessQueues(IMG_TRUE);
1505 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT;
1506 }
1507#endif /* defined(SUPPORT_PVRSRV_DEVICE_CLASS) */
1508
1509 return PVRSRV_OK;
1510}
1511
1512
1513/*!
1514******************************************************************************
1515
1516 @Function PVRSRVDeviceLISR
1517
1518 @Description
1519 OS-independent Device Low-level Interrupt Service Routine
1520
1521 @Input psDeviceNode
1522
1523 @Return IMG_BOOL : Whether any interrupts were serviced
1524
1525******************************************************************************/
1526IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode)
1527{
1528 SYS_DATA *psSysData;
1529 IMG_BOOL bStatus = IMG_FALSE;
1530 IMG_UINT32 ui32InterruptSource;
1531
1532 if(!psDeviceNode)
1533 {
1534 PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceLISR: Invalid params\n"));
1535 goto out;
1536 }
1537 psSysData = psDeviceNode->psSysData;
1538
1539 /* query the SOC/system to see whether this device was the source of the interrupt */
1540 ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode);
1541 if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
1542 {
1543 if(psDeviceNode->pfnDeviceISR != IMG_NULL)
1544 {
1545 bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData);
1546 }
1547
1548 SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit);
1549 }
1550
1551out:
1552 return bStatus;
1553}
1554
1555static IMG_VOID PVRSRVSystemLISR_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
1556{
1557
1558 IMG_BOOL *pbStatus;
1559 IMG_UINT32 *pui32InterruptSource;
1560 IMG_UINT32 *pui32ClearInterrupts;
1561
1562 pbStatus = va_arg(va, IMG_BOOL*);
1563 pui32InterruptSource = va_arg(va, IMG_UINT32*);
1564 pui32ClearInterrupts = va_arg(va, IMG_UINT32*);
1565
1566
1567 if(psDeviceNode->pfnDeviceISR != IMG_NULL)
1568 {
1569 if(*pui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
1570 {
1571 if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData))
1572 {
1573 /* Record if serviced any interrupts. */
1574 *pbStatus = IMG_TRUE;
1575 }
1576 /* Combine the SOC clear bits. */
1577 *pui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit;
1578 }
1579 }
1580}
1581
1582/*!
1583******************************************************************************
1584
1585 @Function PVRSRVSystemLISR
1586
1587 @Description
1588 OS-independent System Low-level Interrupt Service Routine
1589
1590 @Input pvSysData
1591
1592 @Return IMG_BOOL : Whether any interrupts were serviced
1593
1594******************************************************************************/
1595IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData)
1596{
1597 SYS_DATA *psSysData = pvSysData;
1598 IMG_BOOL bStatus = IMG_FALSE;
1599 IMG_UINT32 ui32InterruptSource;
1600 IMG_UINT32 ui32ClearInterrupts = 0;
1601/* PVRSRV_DEVICE_NODE *psDeviceNode;*/
1602
1603 if(!psSysData)
1604 {
1605 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemLISR: Invalid params\n"));
1606/* goto out; */
1607 }
1608 else
1609 {
1610 /* query SOC for source of interrupts */
1611 ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL);
1612
1613 /* only proceed if PVR interrupts */
1614 if(ui32InterruptSource)
1615 {
1616 /* traverse the devices' ISR handlers */
1617 List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
1618 &PVRSRVSystemLISR_ForEachVaCb,
1619 &bStatus,
1620 &ui32InterruptSource,
1621 &ui32ClearInterrupts);
1622
1623 SysClearInterrupts(psSysData, ui32ClearInterrupts);
1624 }
1625/*out:*/
1626 }
1627 return bStatus;
1628}
1629
1630
1631static IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
1632{
1633 if(psDeviceNode->pfnDeviceMISR != IMG_NULL)
1634 {
1635 (*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData);
1636 }
1637}
1638
1639/*!
1640******************************************************************************
1641
1642 @Function PVRSRVMISR
1643
1644 @Input pvSysData
1645
1646 @Description
1647 OS-independent Medium-level Interrupt Service Routine
1648
1649******************************************************************************/
1650IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData)
1651{
1652 SYS_DATA *psSysData = pvSysData;
1653/* PVRSRV_DEVICE_NODE *psDeviceNode; */
1654
1655 if(!psSysData)
1656 {
1657 PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n"));
1658 return;
1659 }
1660
1661 /* Traverse the devices' MISR handlers. */
1662 List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
1663 &PVRSRVMISR_ForEachCb);
1664
1665#if defined(SUPPORT_PVRSRV_DEVICE_CLASS)
1666 /* Process the queues. */
1667 if (PVRSRVProcessQueues(IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED)
1668 {
1669 PVRSRVProcessQueues(IMG_FALSE);
1670 }
1671#endif /* defined(SUPPORT_PVRSRV_DEVICE_CLASS) */
1672
1673 /* signal global event object */
1674 if (psSysData->psGlobalEventObject)
1675 {
1676 IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM;
1677 if(hOSEventKM)
1678 {
1679 OSEventObjectSignalKM(hOSEventKM);
1680 }
1681 }
1682}
1683
1684
1685/*!
1686******************************************************************************
1687
1688 @Function PVRSRVProcessConnect
1689
1690 @Description Inform services that a process has connected.
1691
1692 @Input ui32PID - process ID
1693
1694 @Return PVRSRV_ERROR
1695
1696******************************************************************************/
1697IMG_EXPORT
1698PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags)
1699{
1700 return PVRSRVPerProcessDataConnect(ui32PID, ui32Flags);
1701}
1702
1703
1704/*!
1705******************************************************************************
1706
1707 @Function PVRSRVProcessDisconnect
1708
1709 @Description Inform services that a process has disconnected.
1710
1711 @Input ui32PID - process ID
1712
1713 @Return IMG_VOID
1714
1715******************************************************************************/
1716IMG_EXPORT
1717IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID)
1718{
1719 PVRSRVPerProcessDataDisconnect(ui32PID);
1720}
1721
1722
1723/*!
1724******************************************************************************
1725
1726 @Function PVRSRVSaveRestoreLiveSegments
1727
1728 @Input pArena - the arena the segment was originally allocated from.
1729 pbyBuffer - the system memory buffer set to null to get the size needed.
1730 puiBufSize - size of system memory buffer.
1731 bSave - IMG_TRUE if a save is required
1732
1733 @Description
1734 Function to save or restore Resources Live segments
1735
1736******************************************************************************/
1737PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer,
1738 IMG_SIZE_T *puiBufSize, IMG_BOOL bSave)
1739{
1740 IMG_SIZE_T uiBytesSaved = 0;
1741 IMG_PVOID pvLocalMemCPUVAddr;
1742 RA_SEGMENT_DETAILS sSegDetails;
1743
1744 if (hArena == IMG_NULL)
1745 {
1746 return (PVRSRV_ERROR_INVALID_PARAMS);
1747 }
1748
1749 sSegDetails.uiSize = 0;
1750 sSegDetails.sCpuPhyAddr.uiAddr = 0;
1751 sSegDetails.hSegment = 0;
1752
1753 /* walk the arena segments and write live one to the buffer */
1754 while (RA_GetNextLiveSegment(hArena, &sSegDetails))
1755 {
1756 if (pbyBuffer == IMG_NULL)
1757 {
1758 /* calc buffer required */
1759 uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
1760 }
1761 else
1762 {
1763 if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize)
1764 {
1765 return (PVRSRV_ERROR_OUT_OF_MEMORY);
1766 }
1767
1768 PVR_DPF((
1769 PVR_DBG_MESSAGE,
1770 "PVRSRVSaveRestoreLiveSegments: Base " CPUPADDR_FMT " size %" SIZE_T_FMT_LEN "x",
1771 sSegDetails.sCpuPhyAddr.uiAddr,
1772 sSegDetails.uiSize));
1773
1774 /* Map the device's local memory area onto the host. */
1775 pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr,
1776 sSegDetails.uiSize,
1777 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
1778 IMG_NULL);
1779 if (pvLocalMemCPUVAddr == IMG_NULL)
1780 {
1781 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host"));
1782 return (PVRSRV_ERROR_OUT_OF_MEMORY);
1783 }
1784
1785 if (bSave)
1786 {
1787 /* write segment size then segment data */
1788 OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize));
1789 pbyBuffer += sizeof(sSegDetails.uiSize);
1790
1791 OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize);
1792 pbyBuffer += sSegDetails.uiSize;
1793 }
1794 else
1795 {
1796 IMG_UINT32 uiSize;
1797 /* reag segment size and validate */
1798 OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize));
1799
1800 if (uiSize != sSegDetails.uiSize)
1801 {
1802 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error"));
1803 }
1804 else
1805 {
1806 pbyBuffer += sizeof(sSegDetails.uiSize);
1807
1808 OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize);
1809 pbyBuffer += sSegDetails.uiSize;
1810 }
1811 }
1812
1813
1814 uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
1815
1816 OSUnMapPhysToLin(pvLocalMemCPUVAddr,
1817 sSegDetails.uiSize,
1818 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
1819 IMG_NULL);
1820 }
1821 }
1822
1823 if (pbyBuffer == IMG_NULL)
1824 {
1825 *puiBufSize = uiBytesSaved;
1826 }
1827
1828 return (PVRSRV_OK);
1829}
1830
1831
1832/*!
1833 ******************************************************************************
1834
1835 @Function PVRSRVGetErrorStringKM
1836
1837 @Description Returns a text string relating to the PVRSRV_ERROR enum.
1838
1839 @Note case statement used rather than an indexed arrary to ensure text is
1840 synchronised with the correct enum
1841
1842 @Input eError : PVRSRV_ERROR enum
1843
1844 @Return const IMG_CHAR * : Text string
1845
1846 @Note Must be kept in sync with servicesext.h
1847
1848******************************************************************************/
1849
1850IMG_EXPORT
1851const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError)
1852{
1853/* PRQA S 5087 1 */ /* include file required here */
1854#include "pvrsrv_errors.h"
1855}
1856
1857static IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
1858{
1859 if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
1860 {
1861 /* Call the device's callback function. */
1862 (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
1863 }
1864}
1865
1866/*!
1867******************************************************************************
1868
1869 @Function PVRSRVScheduleDeviceCallbacks
1870
1871 @Description Schedule all device callbacks
1872
1873 @Return IMG_VOID
1874
1875******************************************************************************/
1876IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID)
1877{
1878 SYS_DATA *psSysData;
1879/* PVRSRV_DEVICE_NODE *psDeviceNode;*/
1880
1881 SysAcquireData(&psSysData);
1882
1883 /*for all the device, invoke the callback function*/
1884 List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
1885 &PVRSRVCommandCompleteCallbacks_ForEachCb);
1886}
1887
1888/*!
1889******************************************************************************
1890
1891 @Function PVRSRVScheduleDevices
1892
1893 @Description Schedules all Services-Managed Devices to check their pending
1894 command queues. The intention is that ScheduleDevices be called by the
1895 3rd party BC driver after it has finished writing new data to its output
1896 texture.
1897
1898 @Return IMG_VOID
1899
1900******************************************************************************/
1901IMG_EXPORT
1902IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID)
1903{
1904 PVRSRVScheduleDeviceCallbacks();
1905}
1906
1907/*****************************************************************************
1908 End of file (pvrsrv.c)
1909*****************************************************************************/