diff options
Diffstat (limited to 'jacinto6/sgx_src/eurasia_km/services4/srvkm/env/linux/pvr_sync_common.c')
-rw-r--r-- | jacinto6/sgx_src/eurasia_km/services4/srvkm/env/linux/pvr_sync_common.c | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/jacinto6/sgx_src/eurasia_km/services4/srvkm/env/linux/pvr_sync_common.c b/jacinto6/sgx_src/eurasia_km/services4/srvkm/env/linux/pvr_sync_common.c new file mode 100644 index 0000000..b9120c1 --- /dev/null +++ b/jacinto6/sgx_src/eurasia_km/services4/srvkm/env/linux/pvr_sync_common.c | |||
@@ -0,0 +1,379 @@ | |||
1 | /*************************************************************************/ /*! | ||
2 | @File pvr_sync.c | ||
3 | @Title Kernel driver for Android's sync mechanism | ||
4 | @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved | ||
5 | @License Dual MIT/GPLv2 | ||
6 | |||
7 | The contents of this file are subject to the MIT license as set out below. | ||
8 | |||
9 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
10 | of this software and associated documentation files (the "Software"), to deal | ||
11 | in the Software without restriction, including without limitation the rights | ||
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
13 | copies of the Software, and to permit persons to whom the Software is | ||
14 | furnished to do so, subject to the following conditions: | ||
15 | |||
16 | The above copyright notice and this permission notice shall be included in | ||
17 | all copies or substantial portions of the Software. | ||
18 | |||
19 | Alternatively, the contents of this file may be used under the terms of | ||
20 | the GNU General Public License Version 2 ("GPL") in which case the provisions | ||
21 | of GPL are applicable instead of those above. | ||
22 | |||
23 | If you wish to allow use of your version of this file only under the terms of | ||
24 | GPL, and not to allow others to use your version of this file under the terms | ||
25 | of the MIT license, indicate your decision by deleting the provisions above | ||
26 | and replace them with the notice and other provisions required by GPL as set | ||
27 | out in the file called "GPL-COPYING" included in this distribution. If you do | ||
28 | not delete the provisions above, a recipient may use your version of this file | ||
29 | under the terms of either the MIT license or GPL. | ||
30 | |||
31 | This License is also included in this distribution in the file called | ||
32 | "MIT-COPYING". | ||
33 | |||
34 | EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS | ||
35 | PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING | ||
36 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||
37 | PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR | ||
38 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
39 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
40 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
41 | */ /**************************************************************************/ | ||
42 | |||
43 | #include "pvr_sync_common.h" | ||
44 | #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) | ||
45 | #include "pvr_sync.h" | ||
46 | #else | ||
47 | #include "pvr_fence.h" | ||
48 | #endif | ||
49 | |||
50 | #include <linux/kernel.h> | ||
51 | #include <linux/file.h> | ||
52 | #include <linux/fs.h> | ||
53 | #include <linux/miscdevice.h> | ||
54 | #include <linux/module.h> | ||
55 | #include <linux/syscalls.h> | ||
56 | #include <linux/uaccess.h> | ||
57 | #include <linux/types.h> | ||
58 | #include <linux/atomic.h> | ||
59 | #include <linux/anon_inodes.h> | ||
60 | #include <linux/seq_file.h> | ||
61 | |||
62 | #include "services_headers.h" | ||
63 | #include "sgxutils.h" | ||
64 | #include "ttrace.h" | ||
65 | #include "mutex.h" | ||
66 | #include "lock.h" | ||
67 | |||
68 | static void | ||
69 | CopyKernelSyncInfoToDeviceSyncObject(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, | ||
70 | PVRSRV_DEVICE_SYNC_OBJECT *psSyncObject) | ||
71 | { | ||
72 | psSyncObject->sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; | ||
73 | psSyncObject->sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; | ||
74 | psSyncObject->sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; | ||
75 | psSyncObject->ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; | ||
76 | psSyncObject->ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; | ||
77 | psSyncObject->ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; | ||
78 | } | ||
79 | |||
80 | IMG_BOOL | ||
81 | AddSyncInfoToArray(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, | ||
82 | IMG_UINT32 ui32SyncPointLimit, | ||
83 | IMG_UINT32 *pui32NumRealSyncs, | ||
84 | PVRSRV_KERNEL_SYNC_INFO *apsSyncInfo[]) | ||
85 | { | ||
86 | /* Ran out of syncs. Not much userspace can do about this, since it | ||
87 | * could have been passed multiple merged syncs and doesn't know they | ||
88 | * were merged. Allow this through, but print a warning and stop | ||
89 | * synchronizing. | ||
90 | */ | ||
91 | if(*pui32NumRealSyncs == ui32SyncPointLimit) | ||
92 | { | ||
93 | PVR_DPF((PVR_DBG_WARNING, "%s: Ran out of source syncs %d == %d", | ||
94 | __func__, *pui32NumRealSyncs, | ||
95 | ui32SyncPointLimit)); | ||
96 | return IMG_FALSE; | ||
97 | } | ||
98 | |||
99 | apsSyncInfo[*pui32NumRealSyncs] = psSyncInfo; | ||
100 | (*pui32NumRealSyncs)++; | ||
101 | return IMG_TRUE; | ||
102 | } | ||
103 | |||
104 | IMG_INTERNAL PVRSRV_ERROR | ||
105 | PVRSyncPatchCCBKickSyncInfos(IMG_HANDLE ahSyncs[SGX_MAX_SRC_SYNCS_TA], | ||
106 | PVRSRV_DEVICE_SYNC_OBJECT asDevSyncs[SGX_MAX_SRC_SYNCS_TA], | ||
107 | IMG_UINT32 *pui32NumSrcSyncs) | ||
108 | { | ||
109 | PVRSRV_KERNEL_SYNC_INFO *apsSyncInfo[SGX_MAX_SRC_SYNCS_TA]; | ||
110 | #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) | ||
111 | struct sync_fence *apsFence[SGX_MAX_SRC_SYNCS_TA] = {}; | ||
112 | #else /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_FENCE) */ | ||
113 | struct dma_fence *apsFence[SGX_MAX_SRC_SYNCS_TA] = {}; | ||
114 | #endif | ||
115 | IMG_UINT32 i, ui32NumRealSrcSyncs; | ||
116 | PVRSRV_ERROR eError = PVRSRV_OK; | ||
117 | |||
118 | if(!ExpandAndDeDuplicateFenceSyncs(*pui32NumSrcSyncs, | ||
119 | (IMG_HANDLE *)ahSyncs, | ||
120 | SGX_MAX_SRC_SYNCS_TA, | ||
121 | apsFence, | ||
122 | &ui32NumRealSrcSyncs, | ||
123 | apsSyncInfo)) | ||
124 | { | ||
125 | eError = PVRSRV_ERROR_HANDLE_NOT_FOUND; | ||
126 | goto err_put_fence; | ||
127 | } | ||
128 | |||
129 | /* There should only be one destination sync for a transfer. | ||
130 | * Ultimately this will be patched to two (the sync_pt SYNCINFO, | ||
131 | * and the timeline's SYNCINFO for debugging). | ||
132 | */ | ||
133 | for(i = 0; i < ui32NumRealSrcSyncs; i++) | ||
134 | { | ||
135 | PVRSRV_KERNEL_SYNC_INFO *psSyncInfo = apsSyncInfo[i]; | ||
136 | |||
137 | /* The following code is mostly the same as the texture dependencies | ||
138 | * handling in SGXDoKickKM, but we have to copy it here because it | ||
139 | * must be run while the fence is 'locked' by sync_fence_fdget. | ||
140 | */ | ||
141 | |||
142 | PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_SRC_SYNC, | ||
143 | psSyncInfo, PVRSRV_SYNCOP_SAMPLE); | ||
144 | |||
145 | CopyKernelSyncInfoToDeviceSyncObject(psSyncInfo, &asDevSyncs[i]); | ||
146 | |||
147 | /* Texture dependencies are read operations */ | ||
148 | psSyncInfo->psSyncData->ui32ReadOpsPending++; | ||
149 | |||
150 | /* Finally, patch the sync back into the input array. | ||
151 | * NOTE: The syncs are protected here by the defer-free worker. | ||
152 | */ | ||
153 | ahSyncs[i] = psSyncInfo; | ||
154 | } | ||
155 | |||
156 | /* Updating this allows the PDUMP handling and ROP rollbacks to work | ||
157 | * correctly in SGXDoKickKM. | ||
158 | */ | ||
159 | *pui32NumSrcSyncs = ui32NumRealSrcSyncs; | ||
160 | |||
161 | err_put_fence: | ||
162 | for(i = 0; i < SGX_MAX_SRC_SYNCS_TA && apsFence[i]; i++) | ||
163 | #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) | ||
164 | sync_fence_put(apsFence[i]); | ||
165 | #else | ||
166 | dma_fence_put(apsFence[i]); | ||
167 | #endif | ||
168 | return eError; | ||
169 | } | ||
170 | |||
171 | /* Patching for TQ fence in queueBuffer() */ | ||
172 | IMG_INTERNAL PVRSRV_ERROR | ||
173 | PVRSyncPatchTransferSyncInfos(IMG_HANDLE ahSyncs[SGX_MAX_SRC_SYNCS_TA], | ||
174 | PVRSRV_DEVICE_SYNC_OBJECT asDevSyncs[SGX_MAX_SRC_SYNCS_TA], | ||
175 | IMG_UINT32 *pui32NumSrcSyncs) | ||
176 | { | ||
177 | struct PVR_ALLOC_SYNC_DATA *psTransferSyncData; | ||
178 | PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; | ||
179 | PVRSRV_ERROR eError = PVRSRV_OK; | ||
180 | |||
181 | if (*pui32NumSrcSyncs != 1) | ||
182 | { | ||
183 | PVR_DPF((PVR_DBG_ERROR, "%s: Invalid number of syncs (%d), clamping " | ||
184 | "to 1", __func__, *pui32NumSrcSyncs)); | ||
185 | } | ||
186 | |||
187 | psTransferSyncData = PVRSyncAllocFDGet((int)ahSyncs[0]); | ||
188 | |||
189 | if (!psTransferSyncData) | ||
190 | { | ||
191 | PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get PVR_SYNC_DATA from " | ||
192 | "supplied fd", __func__)); | ||
193 | eError = PVRSRV_ERROR_HANDLE_NOT_FOUND; | ||
194 | goto err_out; | ||
195 | } | ||
196 | |||
197 | /* There should only be one destination sync for a transfer. | ||
198 | * Ultimately this will be patched to two (the sync_pt SYNCINFO, | ||
199 | * and the timeline's SYNCINFO for debugging). | ||
200 | */ | ||
201 | psSyncInfo = psTransferSyncData->psSyncInfo->psBase; | ||
202 | |||
203 | /* The following code is mostly the same as the texture dependencies | ||
204 | * handling in SGXDoKickKM, but we have to copy it here because it | ||
205 | * must be run while the fence is 'locked' by sync_fence_fdget. | ||
206 | */ | ||
207 | |||
208 | PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_SRC_SYNC, | ||
209 | psSyncInfo, PVRSRV_SYNCOP_SAMPLE); | ||
210 | |||
211 | CopyKernelSyncInfoToDeviceSyncObject(psSyncInfo, &asDevSyncs[0]); | ||
212 | CopyKernelSyncInfoToDeviceSyncObject(psTransferSyncData->psTimeline->psSyncInfo->psBase, | ||
213 | &asDevSyncs[1]); | ||
214 | |||
215 | /* Treat fence TQs as write operations */ | ||
216 | psSyncInfo->psSyncData->ui32WriteOpsPending++; | ||
217 | psTransferSyncData->psTimeline->psSyncInfo->psBase->psSyncData->ui32WriteOpsPending++; | ||
218 | |||
219 | /* Finally, patch the sync back into the input array. | ||
220 | * NOTE: The syncs are protected here by the defer-free worker. | ||
221 | */ | ||
222 | ahSyncs[0] = psSyncInfo; | ||
223 | ahSyncs[1] = psTransferSyncData->psTimeline->psSyncInfo->psBase; | ||
224 | |||
225 | /* Updating this allows the PDUMP handling and ROP rollbacks to work | ||
226 | * correctly in SGXDoKickKM. | ||
227 | */ | ||
228 | *pui32NumSrcSyncs = 2; | ||
229 | |||
230 | fput(psTransferSyncData->psFile); | ||
231 | err_out: | ||
232 | return eError; | ||
233 | } | ||
234 | |||
235 | |||
236 | /* NOTE: This returns an array of sync_fences which need to be 'put' | ||
237 | * or they will leak. | ||
238 | */ | ||
239 | /* Display side patching */ | ||
240 | IMG_INTERNAL PVRSRV_ERROR | ||
241 | PVRSyncFencesToSyncInfos(PVRSRV_KERNEL_SYNC_INFO *apsSyncs[], | ||
242 | IMG_UINT32 *pui32NumSyncs, | ||
243 | #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) | ||
244 | struct sync_fence *apsFence[SGX_MAX_SRC_SYNCS_TA] | ||
245 | #else /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_FENCE) */ | ||
246 | struct dma_fence *apsFence[SGX_MAX_SRC_SYNCS_TA] | ||
247 | #endif | ||
248 | ) | ||
249 | { | ||
250 | PVRSRV_KERNEL_SYNC_INFO *apsSyncInfo[SGX_MAX_SRC_SYNCS_TA]; | ||
251 | IMG_UINT32 i, ui32NumRealSrcSyncs; | ||
252 | PVRSRV_ERROR eError = PVRSRV_OK; | ||
253 | |||
254 | #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) | ||
255 | memset(apsFence, 0, sizeof(struct sync_fence *) * SGX_MAX_SRC_SYNCS_TA); | ||
256 | #else /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_FENCE) */ | ||
257 | memset(apsFence, 0, sizeof(struct dma_fence *) * SGX_MAX_SRC_SYNCS_TA); | ||
258 | #endif | ||
259 | |||
260 | if(!ExpandAndDeDuplicateFenceSyncs(*pui32NumSyncs, | ||
261 | (IMG_HANDLE *)apsSyncs, | ||
262 | *pui32NumSyncs, | ||
263 | apsFence, | ||
264 | &ui32NumRealSrcSyncs, | ||
265 | apsSyncInfo)) | ||
266 | { | ||
267 | for(i = 0; i < SGX_MAX_SRC_SYNCS_TA && apsFence[i]; i++) | ||
268 | #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) | ||
269 | sync_fence_put(apsFence[i]); | ||
270 | #else /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_FENCE) */ | ||
271 | dma_fence_put(apsFence[i]); | ||
272 | #endif | ||
273 | |||
274 | return PVRSRV_ERROR_HANDLE_NOT_FOUND; | ||
275 | } | ||
276 | |||
277 | /* We don't expect to see merged syncs here. Abort if that happens. | ||
278 | * Allow through cases where the same fence was specified more than | ||
279 | * once -- we can handle that without reallocation of memory. | ||
280 | */ | ||
281 | PVR_ASSERT(ui32NumRealSrcSyncs <= *pui32NumSyncs); | ||
282 | |||
283 | for(i = 0; i < ui32NumRealSrcSyncs; i++) | ||
284 | apsSyncs[i] = apsSyncInfo[i]; | ||
285 | |||
286 | *pui32NumSyncs = ui32NumRealSrcSyncs; | ||
287 | //PVR_DPF((PVR_DBG_ERROR, "%s END HERE", __func__)); | ||
288 | return eError; | ||
289 | } | ||
290 | |||
291 | /*PVRSRV_ERROR PVRSyncInitServices(void) | ||
292 | { | ||
293 | IMG_BOOL bCreated, bShared[PVRSRV_MAX_CLIENT_HEAPS]; | ||
294 | PVRSRV_HEAP_INFO sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS]; | ||
295 | IMG_UINT32 ui32ClientHeapCount = 0; | ||
296 | PVRSRV_PER_PROCESS_DATA *psPerProc; | ||
297 | PVRSRV_ERROR eError; | ||
298 | |||
299 | LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); | ||
300 | |||
301 | gsSyncServicesConnection.ui32Pid = OSGetCurrentProcessIDKM(); | ||
302 | |||
303 | eError = PVRSRVProcessConnect(gsSyncServicesConnection.ui32Pid, 0); | ||
304 | if (eError != PVRSRV_OK) | ||
305 | { | ||
306 | PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRVProcessConnect failed", | ||
307 | __func__)); | ||
308 | goto err_unlock; | ||
309 | } | ||
310 | |||
311 | psPerProc = PVRSRVFindPerProcessData(); | ||
312 | if (!psPerProc) | ||
313 | { | ||
314 | PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRVFindPerProcessData failed", | ||
315 | __func__)); | ||
316 | goto err_disconnect; | ||
317 | } | ||
318 | |||
319 | eError = PVRSRVAcquireDeviceDataKM(0, PVRSRV_DEVICE_TYPE_SGX, | ||
320 | &gsSyncServicesConnection.hDevCookie); | ||
321 | if (eError != PVRSRV_OK) | ||
322 | { | ||
323 | PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRVAcquireDeviceDataKM failed", | ||
324 | __func__)); | ||
325 | goto err_disconnect; | ||
326 | } | ||
327 | |||
328 | if (!gsSyncServicesConnection.hDevCookie) | ||
329 | { | ||
330 | PVR_DPF((PVR_DBG_ERROR, "%s: hDevCookie is NULL", __func__)); | ||
331 | goto err_disconnect; | ||
332 | } | ||
333 | |||
334 | eError = PVRSRVCreateDeviceMemContextKM(gsSyncServicesConnection.hDevCookie, | ||
335 | psPerProc, | ||
336 | &gsSyncServicesConnection.hDevMemContext, | ||
337 | &ui32ClientHeapCount, | ||
338 | &sHeapInfo[0], | ||
339 | &bCreated, | ||
340 | &bShared[0]); | ||
341 | if (eError != PVRSRV_OK) | ||
342 | { | ||
343 | PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRVCreateDeviceMemContextKM failed", | ||
344 | __func__)); | ||
345 | goto err_disconnect; | ||
346 | } | ||
347 | |||
348 | if (!gsSyncServicesConnection.hDevMemContext) | ||
349 | { | ||
350 | PVR_DPF((PVR_DBG_ERROR, "%s: hDevMemContext is NULL", __func__)); | ||
351 | goto err_disconnect; | ||
352 | } | ||
353 | |||
354 | err_unlock: | ||
355 | LinuxUnLockMutex(&gPVRSRVLock); | ||
356 | return eError; | ||
357 | |||
358 | err_disconnect: | ||
359 | PVRSRVProcessDisconnect(gsSyncServicesConnection.ui32Pid); | ||
360 | goto err_unlock; | ||
361 | } | ||
362 | |||
363 | void PVRSyncCloseServices(void) | ||
364 | { | ||
365 | IMG_BOOL bDummy; | ||
366 | |||
367 | LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); | ||
368 | |||
369 | PVRSRVDestroyDeviceMemContextKM(gsSyncServicesConnection.hDevCookie, | ||
370 | gsSyncServicesConnection.hDevMemContext, | ||
371 | &bDummy); | ||
372 | gsSyncServicesConnection.hDevMemContext = NULL; | ||
373 | gsSyncServicesConnection.hDevCookie = NULL; | ||
374 | |||
375 | PVRSRVProcessDisconnect(gsSyncServicesConnection.ui32Pid); | ||
376 | gsSyncServicesConnection.ui32Pid = 0; | ||
377 | |||
378 | LinuxUnLockMutex(&gPVRSRVLock); | ||
379 | }*/ | ||