1 /*************************************************************************/ /*!
3 @Title PVR Bridge Module (kernel side)
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description Receives calls from the user portion of services and
6 despatches them to functions in the kernel portion.
7 @License Dual MIT/GPLv2
9 The contents of this file are subject to the MIT license as set out below.
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
18 The above copyright notice and this permission notice shall be included in
19 all copies or substantial portions of the Software.
21 Alternatively, the contents of this file may be used under the terms of
22 the GNU General Public License Version 2 ("GPL") in which case the provisions
23 of GPL are applicable instead of those above.
25 If you wish to allow use of your version of this file only under the terms of
26 GPL, and not to allow others to use your version of this file under the terms
27 of the MIT license, indicate your decision by deleting the provisions above
28 and replace them with the notice and other provisions required by GPL as set
29 out in the file called "GPL-COPYING" included in this distribution. If you do
30 not delete the provisions above, a recipient may use your version of this file
31 under the terms of either the MIT license or GPL.
33 This License is also included in this distribution in the file called
36 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
37 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
39 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
40 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
41 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
42 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 */ /**************************************************************************/
45 #include "pvr_bridge.h"
46 #include "connection_server.h"
47 #include "syscommon.h"
48 #include "pvr_debug.h"
49 #include "pvr_debugfs.h"
50 #include "private_data.h"
52 #include "driverlock.h"
54 #if defined(SUPPORT_DRM)
57 #if defined(PVR_DRM_SECURE_AUTH_EXPORT)
58 #include "env_connection.h"
60 #endif /* defined(SUPPORT_DRM) */
63 #if defined(SUPPORT_RGX)
64 #include "rgx_bridge.h"
68 #include "common_srvcore_bridge.h"
69 #include "cache_defines.h"
71 #if defined(MODULE_TEST)
72 /************************************************************************/
73 // additional includes for services testing
74 /************************************************************************/
75 #include "pvr_test_bridge.h"
76 #include "kern_test.h"
77 /************************************************************************/
78 // end of additional includes
79 /************************************************************************/
83 #if defined(SUPPORT_DRM)
84 #define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
86 #define PRIVATE_DATA(pFile) ((pFile)->private_data)
89 #if defined(DEBUG_BRIDGE_KM)
90 static PVR_DEBUGFS_ENTRY_DATA *gpsPVRDebugFSBridgeStatsEntry = NULL;
91 static struct seq_operations gsBridgeStatsReadOps;
94 PVRSRV_ERROR RegisterPDUMPFunctions(void);
95 #if defined(SUPPORT_DISPLAY_CLASS)
96 PVRSRV_ERROR RegisterDCFunctions(void);
98 PVRSRV_ERROR RegisterMMFunctions(void);
99 PVRSRV_ERROR RegisterCMMFunctions(void);
100 PVRSRV_ERROR RegisterPDUMPMMFunctions(void);
101 PVRSRV_ERROR RegisterPDUMPCMMFunctions(void);
102 PVRSRV_ERROR RegisterSRVCOREFunctions(void);
103 PVRSRV_ERROR RegisterSYNCFunctions(void);
104 #if defined(SUPPORT_INSECURE_EXPORT)
105 PVRSRV_ERROR RegisterSYNCEXPORTFunctions(void);
107 #if defined(SUPPORT_SECURE_EXPORT)
108 PVRSRV_ERROR RegisterSYNCSEXPORTFunctions(void);
110 #if defined (SUPPORT_RGX)
111 PVRSRV_ERROR RegisterRGXINITFunctions(void);
112 PVRSRV_ERROR RegisterRGXTA3DFunctions(void);
113 PVRSRV_ERROR RegisterRGXTQFunctions(void);
114 PVRSRV_ERROR RegisterRGXCMPFunctions(void);
115 PVRSRV_ERROR RegisterBREAKPOINTFunctions(void);
116 PVRSRV_ERROR RegisterDEBUGMISCFunctions(void);
117 PVRSRV_ERROR RegisterRGXPDUMPFunctions(void);
118 PVRSRV_ERROR RegisterRGXHWPERFFunctions(void);
119 #if defined(RGX_FEATURE_RAY_TRACING)
120 PVRSRV_ERROR RegisterRGXRAYFunctions(void);
121 #endif /* RGX_FEATURE_RAY_TRACING */
122 PVRSRV_ERROR RegisterREGCONFIGFunctions(void);
123 PVRSRV_ERROR RegisterTIMERQUERYFunctions(void);
124 #endif /* SUPPORT_RGX */
125 #if (CACHEFLUSH_TYPE == CACHEFLUSH_GENERIC)
126 PVRSRV_ERROR RegisterCACHEGENERICFunctions(void);
128 #if defined(SUPPORT_SECURE_EXPORT)
129 PVRSRV_ERROR RegisterSMMFunctions(void);
131 #if defined(SUPPORT_PMMIF)
132 PVRSRV_ERROR RegisterPMMIFFunctions(void);
134 PVRSRV_ERROR RegisterPVRTLFunctions(void);
135 #if defined(PVR_RI_DEBUG)
136 PVRSRV_ERROR RegisterRIFunctions(void);
138 #if defined(SUPPORT_ION)
139 PVRSRV_ERROR RegisterDMABUFFunctions(void);
142 /* These and their friends above will go when full bridge gen comes in */
144 LinuxBridgeInit(void);
146 LinuxBridgeDeInit(void);
149 LinuxBridgeInit(void)
152 #if defined(DEBUG_BRIDGE_KM)
155 iResult = PVRDebugFSCreateEntry("bridge_stats",
157 &gsBridgeStatsReadOps,
159 &g_BridgeDispatchTable[0],
160 &gpsPVRDebugFSBridgeStatsEntry);
163 return PVRSRV_ERROR_OUT_OF_MEMORY;
167 eError = RegisterSRVCOREFunctions();
168 if (eError != PVRSRV_OK)
173 eError = RegisterSYNCFunctions();
174 if (eError != PVRSRV_OK)
179 #if defined(SUPPORT_INSECURE_EXPORT)
180 eError = RegisterSYNCEXPORTFunctions();
181 if (eError != PVRSRV_OK)
186 #if defined(SUPPORT_SECURE_EXPORT)
187 eError = RegisterSYNCSEXPORTFunctions();
188 if (eError != PVRSRV_OK)
194 eError = RegisterPDUMPFunctions();
195 if (eError != PVRSRV_OK)
199 eError = RegisterMMFunctions();
200 if (eError != PVRSRV_OK)
204 eError = RegisterCMMFunctions();
205 if (eError != PVRSRV_OK)
209 eError = RegisterPDUMPMMFunctions();
210 if (eError != PVRSRV_OK)
214 eError = RegisterPDUMPCMMFunctions();
215 if (eError != PVRSRV_OK)
220 #if defined(SUPPORT_PMMIF)
221 eError = RegisterPMMIFFunctions();
222 if (eError != PVRSRV_OK)
228 #if defined(SUPPORT_ION)
229 eError = RegisterDMABUFFunctions();
230 if (eError != PVRSRV_OK)
236 #if defined(SUPPORT_DISPLAY_CLASS)
237 eError = RegisterDCFunctions();
238 if (eError != PVRSRV_OK)
244 #if (CACHEFLUSH_TYPE == CACHEFLUSH_GENERIC)
245 eError = RegisterCACHEGENERICFunctions();
246 if (eError != PVRSRV_OK)
252 #if defined(SUPPORT_SECURE_EXPORT)
253 eError = RegisterSMMFunctions();
254 if (eError != PVRSRV_OK)
260 eError = RegisterPVRTLFunctions();
261 if (eError != PVRSRV_OK)
266 #if defined(PVR_RI_DEBUG)
267 eError = RegisterRIFunctions();
268 if (eError != PVRSRV_OK)
274 #if defined (SUPPORT_RGX)
275 eError = RegisterRGXTQFunctions();
276 if (eError != PVRSRV_OK)
281 eError = RegisterRGXCMPFunctions();
282 if (eError != PVRSRV_OK)
287 eError = RegisterRGXINITFunctions();
288 if (eError != PVRSRV_OK)
293 eError = RegisterRGXTA3DFunctions();
294 if (eError != PVRSRV_OK)
299 eError = RegisterBREAKPOINTFunctions();
300 if (eError != PVRSRV_OK)
305 eError = RegisterDEBUGMISCFunctions();
306 if (eError != PVRSRV_OK)
311 eError = RegisterRGXPDUMPFunctions();
312 if (eError != PVRSRV_OK)
317 eError = RegisterRGXHWPERFFunctions();
318 if (eError != PVRSRV_OK)
323 #if defined(RGX_FEATURE_RAY_TRACING)
324 eError = RegisterRGXRAYFunctions();
325 if (eError != PVRSRV_OK)
329 #endif /* RGX_FEATURE_RAY_TRACING */
331 eError = RegisterREGCONFIGFunctions();
332 if (eError != PVRSRV_OK)
337 eError = RegisterTIMERQUERYFunctions();
338 if (eError != PVRSRV_OK)
343 #endif /* SUPPORT_RGX */
349 LinuxBridgeDeInit(void)
351 #if defined(DEBUG_BRIDGE_KM)
352 PVRDebugFSRemoveEntry(gpsPVRDebugFSBridgeStatsEntry);
353 gpsPVRDebugFSBridgeStatsEntry = NULL;
357 #if defined(DEBUG_BRIDGE_KM)
358 static void *BridgeStatsSeqStart(struct seq_file *psSeqFile, loff_t *puiPosition)
360 PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psDispatchTable = (PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *)psSeqFile->private;
362 OSAcquireBridgeLock();
364 if (psDispatchTable == NULL || (*puiPosition) > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
369 if ((*puiPosition) == 0)
371 return SEQ_START_TOKEN;
374 return &(psDispatchTable[(*puiPosition) - 1]);
377 static void BridgeStatsSeqStop(struct seq_file *psSeqFile, void *pvData)
379 PVR_UNREFERENCED_PARAMETER(psSeqFile);
380 PVR_UNREFERENCED_PARAMETER(pvData);
382 OSReleaseBridgeLock();
385 static void *BridgeStatsSeqNext(struct seq_file *psSeqFile,
389 PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psDispatchTable = (PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *)psSeqFile->private;
391 PVR_UNREFERENCED_PARAMETER(pvData);
395 if ((*puiPosition) > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
400 return &(psDispatchTable[(*puiPosition) - 1]);
403 static int BridgeStatsSeqShow(struct seq_file *psSeqFile, void *pvData)
405 if (pvData == SEQ_START_TOKEN)
407 seq_printf(psSeqFile,
408 "Total ioctl call count = %u\n"
409 "Total number of bytes copied via copy_from_user = %u\n"
410 "Total number of bytes copied via copy_to_user = %u\n"
411 "Total number of bytes copied via copy_*_user = %u\n\n"
412 "%-60s | %-48s | %10s | %20s | %10s\n",
413 g_BridgeGlobalStats.ui32IOCTLCount,
414 g_BridgeGlobalStats.ui32TotalCopyFromUserBytes,
415 g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
416 g_BridgeGlobalStats.ui32TotalCopyFromUserBytes + g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
420 "copy_from_user Bytes",
421 "copy_to_user Bytes");
423 else if (pvData != NULL)
425 PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry = ( PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *)pvData;
427 seq_printf(psSeqFile,
428 "%-60s %-48s %-10u %-20u %-10u\n",
430 psEntry->pszFunctionName,
431 psEntry->ui32CallCount,
432 psEntry->ui32CopyFromUserTotalBytes,
433 psEntry->ui32CopyToUserTotalBytes);
439 static struct seq_operations gsBridgeStatsReadOps =
441 .start = BridgeStatsSeqStart,
442 .stop = BridgeStatsSeqStop,
443 .next = BridgeStatsSeqNext,
444 .show = BridgeStatsSeqShow,
446 #endif /* defined(DEBUG_BRIDGE_KM) */
449 #if defined(SUPPORT_DRM)
451 PVRSRV_BridgeDispatchKM(struct drm_device *dev, void *arg, struct drm_file *pFile)
454 PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int unref__ ioctlCmd, unsigned long arg)
457 #if !defined(SUPPORT_DRM)
458 PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg;
459 PVRSRV_BRIDGE_PACKAGE sBridgePackageKM;
461 PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM;
462 CONNECTION_DATA *psConnection;
463 IMG_INT err = -EFAULT;
465 OSAcquireBridgeLock();
467 psConnection = LinuxConnectionFromFile(pFile);
468 if(psConnection == IMG_NULL)
470 PVR_DPF((PVR_DBG_ERROR, "%s: Connection is closed", __FUNCTION__));
471 OSReleaseBridgeLock();
475 #if defined(SUPPORT_DRM)
476 PVR_UNREFERENCED_PARAMETER(dev);
478 psBridgePackageKM = (PVRSRV_BRIDGE_PACKAGE *)arg;
479 PVR_ASSERT(psBridgePackageKM != IMG_NULL);
481 PVR_UNREFERENCED_PARAMETER(ioctlCmd);
483 psBridgePackageKM = &sBridgePackageKM;
485 if(!OSAccessOK(PVR_VERIFY_WRITE,
487 sizeof(PVRSRV_BRIDGE_PACKAGE)))
489 PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments",
492 goto unlock_and_return;
496 if(OSCopyFromUser(IMG_NULL,
499 sizeof(PVRSRV_BRIDGE_PACKAGE))
502 goto unlock_and_return;
506 #if defined(DEBUG_BRIDGE_CALLS)
508 IMG_UINT32 mangledID;
509 mangledID = psBridgePackageKM->ui32BridgeID;
511 psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);
513 PVR_DPF((PVR_DBG_WARNING, "Bridge ID (x%8x) %8u (mangled: x%8x) ", psBridgePackageKM->ui32BridgeID, psBridgePackageKM->ui32BridgeID, mangledID));
516 psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);
519 err = BridgedDispatchKM(psConnection, psBridgePackageKM);
521 #if !defined(SUPPORT_DRM)
524 OSReleaseBridgeLock();
529 #if defined(CONFIG_COMPAT)
530 #if defined(SUPPORT_DRM)
535 PVRSRV_BridgeCompatDispatchKM(struct file *pFile,
536 unsigned int unref__ ioctlCmd,
539 struct bridge_package_from_32
541 IMG_UINT32 bridge_id; /*!< ioctl/drvesc index */
542 IMG_UINT32 size; /*!< size of structure */
543 IMG_UINT32 addr_param_in; /*!< input data buffer */
544 IMG_UINT32 in_buffer_size; /*!< size of input data buffer */
545 IMG_UINT32 addr_param_out; /*!< output data buffer */
546 IMG_UINT32 out_buffer_size; /*!< size of output data buffer */
549 IMG_INT err = -EFAULT;
550 PVRSRV_BRIDGE_PACKAGE params_for_64;
551 struct bridge_package_from_32 params;
552 struct bridge_package_from_32 * const params_addr = ¶ms;
553 #if defined(SUPPORT_DRM)
554 struct drm_file *file_priv;
556 CONNECTION_DATA *psConnection;
558 // make sure there is no padding inserted by compiler
559 PVR_ASSERT(sizeof(struct bridge_package_from_32) == 6 * sizeof(IMG_UINT32));
561 OSAcquireBridgeLock();
563 #if !defined(SUPPORT_DRM)
564 psConnection = LinuxConnectionFromFile(pFile);
566 file_priv = pFile->private_data;
567 psConnection = LinuxConnectionFromFile(file_priv);
569 if(psConnection == IMG_NULL)
571 PVR_DPF((PVR_DBG_ERROR, "%s: Connection is closed", __FUNCTION__));
572 goto unlock_and_return;
575 if(!OSAccessOK(PVR_VERIFY_READ, (void *) arg,
576 sizeof(struct bridge_package_from_32)))
578 PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments",
581 goto unlock_and_return;
584 if(OSCopyFromUser(NULL, params_addr, (void*) arg,
585 sizeof(struct bridge_package_from_32))
588 goto unlock_and_return;
591 PVR_ASSERT(params_addr->size == sizeof(struct bridge_package_from_32));
593 params_addr->bridge_id = PVRSRV_GET_BRIDGE_ID(params_addr->bridge_id);
595 #if defined(DEBUG_BRIDGE_KM)
596 PVR_DPF((PVR_DBG_MESSAGE, "ioctl %s -> func %s",
597 g_BridgeDispatchTable[params_addr->bridge_id].pszIOCName,
598 g_BridgeDispatchTable[params_addr->bridge_id].pszFunctionName));
601 params_for_64.ui32BridgeID = params_addr->bridge_id;
602 params_for_64.ui32Size = sizeof(params_for_64);
603 params_for_64.pvParamIn = (void*) ((size_t) params_addr->addr_param_in);
604 params_for_64.pvParamOut = (void*) ((size_t) params_addr->addr_param_out);
605 params_for_64.ui32InBufferSize = params_addr->in_buffer_size;
606 params_for_64.ui32OutBufferSize = params_addr->out_buffer_size;
608 err = BridgedDispatchKM(psConnection, ¶ms_for_64);
611 OSReleaseBridgeLock();
614 #endif /* defined(CONFIG_COMPAT) */