1 /*******************************************************************************
3 @Title Server bridge for devicememhistory
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description Implements the server side of the bridge for devicememhistory
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 *******************************************************************************/
44 #include <linux/uaccess.h>
48 #include "devicemem_history_server.h"
50 #include "common_devicememhistory_bridge.h"
53 #include "pvr_debug.h"
54 #include "connection_server.h"
55 #include "pvr_bridge.h"
56 #if defined(SUPPORT_RGX)
57 #include "rgx_bridge.h"
62 #include <linux/slab.h>
66 /* ***************************************************************************
67 * Server-side bridge entry points
70 static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX,
71 "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX");
74 PVRSRVBridgeDevicememHistoryMap(IMG_UINT32 ui32DispatchTableEntry,
75 IMG_UINT8 * psDevicememHistoryMapIN_UI8,
76 IMG_UINT8 * psDevicememHistoryMapOUT_UI8,
77 CONNECTION_DATA * psConnection)
79 PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP *psDevicememHistoryMapIN =
80 (PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP *) IMG_OFFSET_ADDR(psDevicememHistoryMapIN_UI8,
82 PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP *psDevicememHistoryMapOUT =
83 (PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP *) IMG_OFFSET_ADDR(psDevicememHistoryMapOUT_UI8,
86 IMG_HANDLE hPMR = psDevicememHistoryMapIN->hPMR;
88 IMG_CHAR *uiTextInt = NULL;
90 IMG_UINT32 ui32NextOffset = 0;
91 IMG_BYTE *pArrayArgsBuffer = NULL;
92 #if !defined(INTEGRITY_OS)
93 IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
96 IMG_UINT32 ui32BufferSize = 0;
97 IMG_UINT64 ui64BufferSize = ((IMG_UINT64) DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) + 0;
99 if (ui64BufferSize > IMG_UINT32_MAX)
101 psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL;
102 goto DevicememHistoryMap_exit;
105 ui32BufferSize = (IMG_UINT32) ui64BufferSize;
107 if (ui32BufferSize != 0)
109 #if !defined(INTEGRITY_OS)
110 /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
111 IMG_UINT32 ui32InBufferOffset =
112 PVR_ALIGN(sizeof(*psDevicememHistoryMapIN), sizeof(unsigned long));
113 IMG_UINT32 ui32InBufferExcessSize =
114 ui32InBufferOffset >=
115 PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
117 bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
118 if (bHaveEnoughSpace)
120 IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psDevicememHistoryMapIN;
122 pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];
127 pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
129 if (!pArrayArgsBuffer)
131 psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
132 goto DevicememHistoryMap_exit;
138 uiTextInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset);
139 ui32NextOffset += DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR);
142 /* Copy the data over */
143 if (DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR) > 0)
146 (NULL, uiTextInt, (const void __user *)psDevicememHistoryMapIN->puiText,
147 DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK)
149 psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
151 goto DevicememHistoryMap_exit;
153 ((IMG_CHAR *) uiTextInt)[(DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) - 1] = '\0';
156 /* Lock over handle lookup. */
157 LockHandle(psConnection->psHandleBase);
159 /* Look up the address from the handle */
160 psDevicememHistoryMapOUT->eError =
161 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
163 hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE);
164 if (unlikely(psDevicememHistoryMapOUT->eError != PVRSRV_OK))
166 UnlockHandle(psConnection->psHandleBase);
167 goto DevicememHistoryMap_exit;
169 /* Release now we have looked up handles. */
170 UnlockHandle(psConnection->psHandleBase);
172 psDevicememHistoryMapOUT->eError =
173 DevicememHistoryMapKM(psPMRInt,
174 psDevicememHistoryMapIN->uiOffset,
175 psDevicememHistoryMapIN->sDevVAddr,
176 psDevicememHistoryMapIN->uiSize,
178 psDevicememHistoryMapIN->ui32Log2PageSize,
179 psDevicememHistoryMapIN->ui32AllocationIndex,
180 &psDevicememHistoryMapOUT->ui32AllocationIndexOut);
182 DevicememHistoryMap_exit:
184 /* Lock over handle lookup cleanup. */
185 LockHandle(psConnection->psHandleBase);
187 /* Unreference the previously looked up handle */
190 PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
191 hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
193 /* Release now we have cleaned up look up handles. */
194 UnlockHandle(psConnection->psHandleBase);
196 /* Allocated space should be equal to the last updated offset */
197 #ifdef PVRSRV_NEED_PVR_ASSERT
198 if (psDevicememHistoryMapOUT->eError == PVRSRV_OK)
199 PVR_ASSERT(ui32BufferSize == ui32NextOffset);
200 #endif /* PVRSRV_NEED_PVR_ASSERT */
202 #if defined(INTEGRITY_OS)
203 if (pArrayArgsBuffer)
205 if (!bHaveEnoughSpace && pArrayArgsBuffer)
207 OSFreeMemNoStats(pArrayArgsBuffer);
212 static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX,
213 "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX");
216 PVRSRVBridgeDevicememHistoryUnmap(IMG_UINT32 ui32DispatchTableEntry,
217 IMG_UINT8 * psDevicememHistoryUnmapIN_UI8,
218 IMG_UINT8 * psDevicememHistoryUnmapOUT_UI8,
219 CONNECTION_DATA * psConnection)
221 PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP *psDevicememHistoryUnmapIN =
222 (PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP *)
223 IMG_OFFSET_ADDR(psDevicememHistoryUnmapIN_UI8, 0);
224 PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP *psDevicememHistoryUnmapOUT =
225 (PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP *)
226 IMG_OFFSET_ADDR(psDevicememHistoryUnmapOUT_UI8, 0);
228 IMG_HANDLE hPMR = psDevicememHistoryUnmapIN->hPMR;
229 PMR *psPMRInt = NULL;
230 IMG_CHAR *uiTextInt = NULL;
232 IMG_UINT32 ui32NextOffset = 0;
233 IMG_BYTE *pArrayArgsBuffer = NULL;
234 #if !defined(INTEGRITY_OS)
235 IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
238 IMG_UINT32 ui32BufferSize = 0;
239 IMG_UINT64 ui64BufferSize = ((IMG_UINT64) DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) + 0;
241 if (ui64BufferSize > IMG_UINT32_MAX)
243 psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL;
244 goto DevicememHistoryUnmap_exit;
247 ui32BufferSize = (IMG_UINT32) ui64BufferSize;
249 if (ui32BufferSize != 0)
251 #if !defined(INTEGRITY_OS)
252 /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
253 IMG_UINT32 ui32InBufferOffset =
254 PVR_ALIGN(sizeof(*psDevicememHistoryUnmapIN), sizeof(unsigned long));
255 IMG_UINT32 ui32InBufferExcessSize =
256 ui32InBufferOffset >=
257 PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
259 bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
260 if (bHaveEnoughSpace)
262 IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psDevicememHistoryUnmapIN;
264 pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];
269 pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
271 if (!pArrayArgsBuffer)
273 psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
274 goto DevicememHistoryUnmap_exit;
280 uiTextInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset);
281 ui32NextOffset += DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR);
284 /* Copy the data over */
285 if (DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR) > 0)
288 (NULL, uiTextInt, (const void __user *)psDevicememHistoryUnmapIN->puiText,
289 DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK)
291 psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
293 goto DevicememHistoryUnmap_exit;
295 ((IMG_CHAR *) uiTextInt)[(DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) - 1] = '\0';
298 /* Lock over handle lookup. */
299 LockHandle(psConnection->psHandleBase);
301 /* Look up the address from the handle */
302 psDevicememHistoryUnmapOUT->eError =
303 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
305 hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE);
306 if (unlikely(psDevicememHistoryUnmapOUT->eError != PVRSRV_OK))
308 UnlockHandle(psConnection->psHandleBase);
309 goto DevicememHistoryUnmap_exit;
311 /* Release now we have looked up handles. */
312 UnlockHandle(psConnection->psHandleBase);
314 psDevicememHistoryUnmapOUT->eError =
315 DevicememHistoryUnmapKM(psPMRInt,
316 psDevicememHistoryUnmapIN->uiOffset,
317 psDevicememHistoryUnmapIN->sDevVAddr,
318 psDevicememHistoryUnmapIN->uiSize,
320 psDevicememHistoryUnmapIN->ui32Log2PageSize,
321 psDevicememHistoryUnmapIN->ui32AllocationIndex,
322 &psDevicememHistoryUnmapOUT->ui32AllocationIndexOut);
324 DevicememHistoryUnmap_exit:
326 /* Lock over handle lookup cleanup. */
327 LockHandle(psConnection->psHandleBase);
329 /* Unreference the previously looked up handle */
332 PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
333 hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
335 /* Release now we have cleaned up look up handles. */
336 UnlockHandle(psConnection->psHandleBase);
338 /* Allocated space should be equal to the last updated offset */
339 #ifdef PVRSRV_NEED_PVR_ASSERT
340 if (psDevicememHistoryUnmapOUT->eError == PVRSRV_OK)
341 PVR_ASSERT(ui32BufferSize == ui32NextOffset);
342 #endif /* PVRSRV_NEED_PVR_ASSERT */
344 #if defined(INTEGRITY_OS)
345 if (pArrayArgsBuffer)
347 if (!bHaveEnoughSpace && pArrayArgsBuffer)
349 OSFreeMemNoStats(pArrayArgsBuffer);
354 static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX,
355 "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX");
358 PVRSRVBridgeDevicememHistoryMapVRange(IMG_UINT32 ui32DispatchTableEntry,
359 IMG_UINT8 * psDevicememHistoryMapVRangeIN_UI8,
360 IMG_UINT8 * psDevicememHistoryMapVRangeOUT_UI8,
361 CONNECTION_DATA * psConnection)
363 PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE *psDevicememHistoryMapVRangeIN =
364 (PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE *)
365 IMG_OFFSET_ADDR(psDevicememHistoryMapVRangeIN_UI8, 0);
366 PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE *psDevicememHistoryMapVRangeOUT =
367 (PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE *)
368 IMG_OFFSET_ADDR(psDevicememHistoryMapVRangeOUT_UI8, 0);
370 IMG_CHAR *uiTextInt = NULL;
372 IMG_UINT32 ui32NextOffset = 0;
373 IMG_BYTE *pArrayArgsBuffer = NULL;
374 #if !defined(INTEGRITY_OS)
375 IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
378 IMG_UINT32 ui32BufferSize = 0;
379 IMG_UINT64 ui64BufferSize = ((IMG_UINT64) DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) + 0;
381 if (ui64BufferSize > IMG_UINT32_MAX)
383 psDevicememHistoryMapVRangeOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL;
384 goto DevicememHistoryMapVRange_exit;
387 ui32BufferSize = (IMG_UINT32) ui64BufferSize;
389 if (ui32BufferSize != 0)
391 #if !defined(INTEGRITY_OS)
392 /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
393 IMG_UINT32 ui32InBufferOffset =
394 PVR_ALIGN(sizeof(*psDevicememHistoryMapVRangeIN), sizeof(unsigned long));
395 IMG_UINT32 ui32InBufferExcessSize =
396 ui32InBufferOffset >=
397 PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
399 bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
400 if (bHaveEnoughSpace)
402 IMG_BYTE *pInputBuffer = (IMG_BYTE *) (void *)psDevicememHistoryMapVRangeIN;
404 pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];
409 pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
411 if (!pArrayArgsBuffer)
413 psDevicememHistoryMapVRangeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
414 goto DevicememHistoryMapVRange_exit;
420 uiTextInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset);
421 ui32NextOffset += DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR);
424 /* Copy the data over */
425 if (DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR) > 0)
428 (NULL, uiTextInt, (const void __user *)psDevicememHistoryMapVRangeIN->puiText,
429 DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK)
431 psDevicememHistoryMapVRangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
433 goto DevicememHistoryMapVRange_exit;
435 ((IMG_CHAR *) uiTextInt)[(DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) - 1] = '\0';
438 psDevicememHistoryMapVRangeOUT->eError =
439 DevicememHistoryMapVRangeKM(psConnection, OSGetDevNode(psConnection),
440 psDevicememHistoryMapVRangeIN->sBaseDevVAddr,
441 psDevicememHistoryMapVRangeIN->ui32ui32StartPage,
442 psDevicememHistoryMapVRangeIN->ui32NumPages,
443 psDevicememHistoryMapVRangeIN->uiAllocSize,
445 psDevicememHistoryMapVRangeIN->ui32Log2PageSize,
446 psDevicememHistoryMapVRangeIN->ui32AllocationIndex,
447 &psDevicememHistoryMapVRangeOUT->ui32AllocationIndexOut);
449 DevicememHistoryMapVRange_exit:
451 /* Allocated space should be equal to the last updated offset */
452 #ifdef PVRSRV_NEED_PVR_ASSERT
453 if (psDevicememHistoryMapVRangeOUT->eError == PVRSRV_OK)
454 PVR_ASSERT(ui32BufferSize == ui32NextOffset);
455 #endif /* PVRSRV_NEED_PVR_ASSERT */
457 #if defined(INTEGRITY_OS)
458 if (pArrayArgsBuffer)
460 if (!bHaveEnoughSpace && pArrayArgsBuffer)
462 OSFreeMemNoStats(pArrayArgsBuffer);
467 static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX,
468 "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX");
471 PVRSRVBridgeDevicememHistoryUnmapVRange(IMG_UINT32 ui32DispatchTableEntry,
472 IMG_UINT8 * psDevicememHistoryUnmapVRangeIN_UI8,
473 IMG_UINT8 * psDevicememHistoryUnmapVRangeOUT_UI8,
474 CONNECTION_DATA * psConnection)
476 PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE *psDevicememHistoryUnmapVRangeIN =
477 (PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE *)
478 IMG_OFFSET_ADDR(psDevicememHistoryUnmapVRangeIN_UI8, 0);
479 PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE *psDevicememHistoryUnmapVRangeOUT =
480 (PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE *)
481 IMG_OFFSET_ADDR(psDevicememHistoryUnmapVRangeOUT_UI8, 0);
483 IMG_CHAR *uiTextInt = NULL;
485 IMG_UINT32 ui32NextOffset = 0;
486 IMG_BYTE *pArrayArgsBuffer = NULL;
487 #if !defined(INTEGRITY_OS)
488 IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
491 IMG_UINT32 ui32BufferSize = 0;
492 IMG_UINT64 ui64BufferSize = ((IMG_UINT64) DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) + 0;
494 if (ui64BufferSize > IMG_UINT32_MAX)
496 psDevicememHistoryUnmapVRangeOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL;
497 goto DevicememHistoryUnmapVRange_exit;
500 ui32BufferSize = (IMG_UINT32) ui64BufferSize;
502 if (ui32BufferSize != 0)
504 #if !defined(INTEGRITY_OS)
505 /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
506 IMG_UINT32 ui32InBufferOffset =
507 PVR_ALIGN(sizeof(*psDevicememHistoryUnmapVRangeIN), sizeof(unsigned long));
508 IMG_UINT32 ui32InBufferExcessSize =
509 ui32InBufferOffset >=
510 PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
512 bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
513 if (bHaveEnoughSpace)
515 IMG_BYTE *pInputBuffer =
516 (IMG_BYTE *) (void *)psDevicememHistoryUnmapVRangeIN;
518 pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];
523 pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
525 if (!pArrayArgsBuffer)
527 psDevicememHistoryUnmapVRangeOUT->eError =
528 PVRSRV_ERROR_OUT_OF_MEMORY;
529 goto DevicememHistoryUnmapVRange_exit;
535 uiTextInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset);
536 ui32NextOffset += DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR);
539 /* Copy the data over */
540 if (DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR) > 0)
543 (NULL, uiTextInt, (const void __user *)psDevicememHistoryUnmapVRangeIN->puiText,
544 DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK)
546 psDevicememHistoryUnmapVRangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
548 goto DevicememHistoryUnmapVRange_exit;
550 ((IMG_CHAR *) uiTextInt)[(DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) - 1] = '\0';
553 psDevicememHistoryUnmapVRangeOUT->eError =
554 DevicememHistoryUnmapVRangeKM(psConnection, OSGetDevNode(psConnection),
555 psDevicememHistoryUnmapVRangeIN->sBaseDevVAddr,
556 psDevicememHistoryUnmapVRangeIN->ui32ui32StartPage,
557 psDevicememHistoryUnmapVRangeIN->ui32NumPages,
558 psDevicememHistoryUnmapVRangeIN->uiAllocSize,
560 psDevicememHistoryUnmapVRangeIN->ui32Log2PageSize,
561 psDevicememHistoryUnmapVRangeIN->ui32AllocationIndex,
562 &psDevicememHistoryUnmapVRangeOUT->
563 ui32AllocationIndexOut);
565 DevicememHistoryUnmapVRange_exit:
567 /* Allocated space should be equal to the last updated offset */
568 #ifdef PVRSRV_NEED_PVR_ASSERT
569 if (psDevicememHistoryUnmapVRangeOUT->eError == PVRSRV_OK)
570 PVR_ASSERT(ui32BufferSize == ui32NextOffset);
571 #endif /* PVRSRV_NEED_PVR_ASSERT */
573 #if defined(INTEGRITY_OS)
574 if (pArrayArgsBuffer)
576 if (!bHaveEnoughSpace && pArrayArgsBuffer)
578 OSFreeMemNoStats(pArrayArgsBuffer);
583 static_assert(DEVMEM_ANNOTATION_MAX_LEN <= IMG_UINT32_MAX,
584 "DEVMEM_ANNOTATION_MAX_LEN must not be larger than IMG_UINT32_MAX");
587 PVRSRVBridgeDevicememHistorySparseChange(IMG_UINT32 ui32DispatchTableEntry,
588 IMG_UINT8 * psDevicememHistorySparseChangeIN_UI8,
589 IMG_UINT8 * psDevicememHistorySparseChangeOUT_UI8,
590 CONNECTION_DATA * psConnection)
592 PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE *psDevicememHistorySparseChangeIN =
593 (PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE *)
594 IMG_OFFSET_ADDR(psDevicememHistorySparseChangeIN_UI8, 0);
595 PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE *psDevicememHistorySparseChangeOUT =
596 (PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE *)
597 IMG_OFFSET_ADDR(psDevicememHistorySparseChangeOUT_UI8, 0);
599 IMG_HANDLE hPMR = psDevicememHistorySparseChangeIN->hPMR;
600 PMR *psPMRInt = NULL;
601 IMG_CHAR *uiTextInt = NULL;
602 IMG_UINT32 *ui32AllocPageIndicesInt = NULL;
603 IMG_UINT32 *ui32FreePageIndicesInt = NULL;
605 IMG_UINT32 ui32NextOffset = 0;
606 IMG_BYTE *pArrayArgsBuffer = NULL;
607 #if !defined(INTEGRITY_OS)
608 IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
611 IMG_UINT32 ui32BufferSize = 0;
612 IMG_UINT64 ui64BufferSize =
613 ((IMG_UINT64) DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) +
614 ((IMG_UINT64) psDevicememHistorySparseChangeIN->ui32AllocPageCount *
615 sizeof(IMG_UINT32)) +
616 ((IMG_UINT64) psDevicememHistorySparseChangeIN->ui32FreePageCount *
617 sizeof(IMG_UINT32)) + 0;
619 if (ui64BufferSize > IMG_UINT32_MAX)
621 psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL;
622 goto DevicememHistorySparseChange_exit;
625 ui32BufferSize = (IMG_UINT32) ui64BufferSize;
627 if (ui32BufferSize != 0)
629 #if !defined(INTEGRITY_OS)
630 /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
631 IMG_UINT32 ui32InBufferOffset =
632 PVR_ALIGN(sizeof(*psDevicememHistorySparseChangeIN), sizeof(unsigned long));
633 IMG_UINT32 ui32InBufferExcessSize =
634 ui32InBufferOffset >=
635 PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 : PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
637 bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
638 if (bHaveEnoughSpace)
640 IMG_BYTE *pInputBuffer =
641 (IMG_BYTE *) (void *)psDevicememHistorySparseChangeIN;
643 pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];
648 pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
650 if (!pArrayArgsBuffer)
652 psDevicememHistorySparseChangeOUT->eError =
653 PVRSRV_ERROR_OUT_OF_MEMORY;
654 goto DevicememHistorySparseChange_exit;
660 uiTextInt = (IMG_CHAR *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset);
661 ui32NextOffset += DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR);
664 /* Copy the data over */
665 if (DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR) > 0)
669 (const void __user *)psDevicememHistorySparseChangeIN->puiText,
670 DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK)
672 psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
674 goto DevicememHistorySparseChange_exit;
676 ((IMG_CHAR *) uiTextInt)[(DEVMEM_ANNOTATION_MAX_LEN * sizeof(IMG_CHAR)) - 1] = '\0';
678 if (psDevicememHistorySparseChangeIN->ui32AllocPageCount != 0)
680 ui32AllocPageIndicesInt =
681 (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset);
683 psDevicememHistorySparseChangeIN->ui32AllocPageCount * sizeof(IMG_UINT32);
686 /* Copy the data over */
687 if (psDevicememHistorySparseChangeIN->ui32AllocPageCount * sizeof(IMG_UINT32) > 0)
690 (NULL, ui32AllocPageIndicesInt,
691 (const void __user *)psDevicememHistorySparseChangeIN->pui32AllocPageIndices,
692 psDevicememHistorySparseChangeIN->ui32AllocPageCount * sizeof(IMG_UINT32)) !=
695 psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
697 goto DevicememHistorySparseChange_exit;
700 if (psDevicememHistorySparseChangeIN->ui32FreePageCount != 0)
702 ui32FreePageIndicesInt =
703 (IMG_UINT32 *) IMG_OFFSET_ADDR(pArrayArgsBuffer, ui32NextOffset);
705 psDevicememHistorySparseChangeIN->ui32FreePageCount * sizeof(IMG_UINT32);
708 /* Copy the data over */
709 if (psDevicememHistorySparseChangeIN->ui32FreePageCount * sizeof(IMG_UINT32) > 0)
712 (NULL, ui32FreePageIndicesInt,
713 (const void __user *)psDevicememHistorySparseChangeIN->pui32FreePageIndices,
714 psDevicememHistorySparseChangeIN->ui32FreePageCount * sizeof(IMG_UINT32)) !=
717 psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
719 goto DevicememHistorySparseChange_exit;
723 /* Lock over handle lookup. */
724 LockHandle(psConnection->psHandleBase);
726 /* Look up the address from the handle */
727 psDevicememHistorySparseChangeOUT->eError =
728 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
730 hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR, IMG_TRUE);
731 if (unlikely(psDevicememHistorySparseChangeOUT->eError != PVRSRV_OK))
733 UnlockHandle(psConnection->psHandleBase);
734 goto DevicememHistorySparseChange_exit;
736 /* Release now we have looked up handles. */
737 UnlockHandle(psConnection->psHandleBase);
739 psDevicememHistorySparseChangeOUT->eError =
740 DevicememHistorySparseChangeKM(psPMRInt,
741 psDevicememHistorySparseChangeIN->uiOffset,
742 psDevicememHistorySparseChangeIN->sDevVAddr,
743 psDevicememHistorySparseChangeIN->uiSize,
745 psDevicememHistorySparseChangeIN->ui32Log2PageSize,
746 psDevicememHistorySparseChangeIN->ui32AllocPageCount,
747 ui32AllocPageIndicesInt,
748 psDevicememHistorySparseChangeIN->ui32FreePageCount,
749 ui32FreePageIndicesInt,
750 psDevicememHistorySparseChangeIN->ui32AllocationIndex,
751 &psDevicememHistorySparseChangeOUT->
752 ui32AllocationIndexOut);
754 DevicememHistorySparseChange_exit:
756 /* Lock over handle lookup cleanup. */
757 LockHandle(psConnection->psHandleBase);
759 /* Unreference the previously looked up handle */
762 PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
763 hPMR, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
765 /* Release now we have cleaned up look up handles. */
766 UnlockHandle(psConnection->psHandleBase);
768 /* Allocated space should be equal to the last updated offset */
769 #ifdef PVRSRV_NEED_PVR_ASSERT
770 if (psDevicememHistorySparseChangeOUT->eError == PVRSRV_OK)
771 PVR_ASSERT(ui32BufferSize == ui32NextOffset);
772 #endif /* PVRSRV_NEED_PVR_ASSERT */
774 #if defined(INTEGRITY_OS)
775 if (pArrayArgsBuffer)
777 if (!bHaveEnoughSpace && pArrayArgsBuffer)
779 OSFreeMemNoStats(pArrayArgsBuffer);
784 /* ***************************************************************************
785 * Server bridge dispatch related glue
788 static POS_LOCK pDEVICEMEMHISTORYBridgeLock;
790 PVRSRV_ERROR InitDEVICEMEMHISTORYBridge(void);
791 void DeinitDEVICEMEMHISTORYBridge(void);
794 * Register all DEVICEMEMHISTORY functions with services
796 PVRSRV_ERROR InitDEVICEMEMHISTORYBridge(void)
798 PVR_LOG_RETURN_IF_ERROR(OSLockCreate(&pDEVICEMEMHISTORYBridgeLock), "OSLockCreate");
800 SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY,
801 PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP,
802 PVRSRVBridgeDevicememHistoryMap, pDEVICEMEMHISTORYBridgeLock);
804 SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY,
805 PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP,
806 PVRSRVBridgeDevicememHistoryUnmap, pDEVICEMEMHISTORYBridgeLock);
808 SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY,
809 PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAPVRANGE,
810 PVRSRVBridgeDevicememHistoryMapVRange, pDEVICEMEMHISTORYBridgeLock);
812 SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY,
813 PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAPVRANGE,
814 PVRSRVBridgeDevicememHistoryUnmapVRange, pDEVICEMEMHISTORYBridgeLock);
816 SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY,
817 PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYSPARSECHANGE,
818 PVRSRVBridgeDevicememHistorySparseChange,
819 pDEVICEMEMHISTORYBridgeLock);
825 * Unregister all devicememhistory functions with services
827 void DeinitDEVICEMEMHISTORYBridge(void)
829 OSLockDestroy(pDEVICEMEMHISTORYBridgeLock);
831 UnsetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY,
832 PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP);
834 UnsetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY,
835 PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP);
837 UnsetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY,
838 PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAPVRANGE);
840 UnsetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY,
841 PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAPVRANGE);
843 UnsetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY,
844 PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYSPARSECHANGE);