1
/**********************************************************************
3
* Copyright (C) Imagination Technologies Ltd. All rights reserved.
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms and conditions of the GNU General Public License,
7
* version 2, as published by the Free Software Foundation.
9
* This program is distributed in the hope it will be useful but, except
10
* as otherwise stated in writing, without any warranty; without even the
11
* implied warranty of merchantability or fitness for a particular purpose.
12
* See the GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License along with
15
* this program; if not, write to the Free Software Foundation, Inc.,
16
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
* The full GNU General Public License is included in this distribution in
19
* the file called "COPYING".
21
* Contact Information:
22
* Imagination Technologies Ltd. <gpl-support@imgtec.com>
23
* Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25
******************************************************************************/
27
#include "services_headers.h"
32
#include <linux/version.h>
33
#include <linux/sched.h>
34
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
35
#include <linux/hardirq.h>
37
#include <asm/hardirq.h>
40
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
41
#include <linux/semaphore.h>
43
#include <asm/semaphore.h>
46
static DEFINE_SEMAPHORE(lock);
48
#define ACQUIRE_SYNC_OBJ do { \
49
if (in_interrupt()) { \
50
printk ("ISR cannot take RESMAN mutex\n"); \
55
#define RELEASE_SYNC_OBJ up (&lock)
59
#define ACQUIRE_SYNC_OBJ
60
#define RELEASE_SYNC_OBJ
64
#define RESMAN_SIGNATURE 0x12345678
66
typedef struct _RESMAN_ITEM_
69
IMG_UINT32 ui32Signature;
71
struct _RESMAN_ITEM_ **ppsThis;
72
struct _RESMAN_ITEM_ *psNext;
75
IMG_UINT32 ui32ResType;
80
RESMAN_FREE_FN pfnFreeResource;
84
typedef struct _RESMAN_CONTEXT_
87
IMG_UINT32 ui32Signature;
89
struct _RESMAN_CONTEXT_ **ppsThis;
90
struct _RESMAN_CONTEXT_ *psNext;
92
PVRSRV_PER_PROCESS_DATA *psPerProc;
94
RESMAN_ITEM *psResItemList;
101
RESMAN_CONTEXT *psContextList;
103
} RESMAN_LIST, *PRESMAN_LIST;
106
PRESMAN_LIST gpsResList = IMG_NULL;
110
static IMPLEMENT_LIST_ANY_VA(RESMAN_ITEM)
111
static IMPLEMENT_LIST_ANY_VA_2(RESMAN_ITEM, IMG_BOOL, IMG_FALSE)
112
static IMPLEMENT_LIST_INSERT(RESMAN_ITEM)
113
static IMPLEMENT_LIST_REMOVE(RESMAN_ITEM)
114
static IMPLEMENT_LIST_REVERSE(RESMAN_ITEM)
116
static IMPLEMENT_LIST_REMOVE(RESMAN_CONTEXT)
117
static IMPLEMENT_LIST_INSERT(RESMAN_CONTEXT)
120
#define PRINT_RESLIST(x, y, z)
122
static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, IMG_BOOL bExecuteCallback, IMG_BOOL bForceCleanup);
124
static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psContext,
125
IMG_UINT32 ui32SearchCriteria,
126
IMG_UINT32 ui32ResType,
128
IMG_UINT32 ui32Param,
129
IMG_BOOL bExecuteCallback);
133
static IMG_VOID ValidateResList(PRESMAN_LIST psResList);
134
#define VALIDATERESLIST() ValidateResList(gpsResList)
136
#define VALIDATERESLIST()
144
PVRSRV_ERROR ResManInit(IMG_VOID)
146
if (gpsResList == IMG_NULL)
149
if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
151
(IMG_VOID **)&gpsResList, IMG_NULL,
152
"Resource Manager List") != PVRSRV_OK)
154
return PVRSRV_ERROR_OUT_OF_MEMORY;
158
gpsResList->psContextList = IMG_NULL;
168
IMG_VOID ResManDeInit(IMG_VOID)
170
if (gpsResList != IMG_NULL)
173
OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*gpsResList), gpsResList, IMG_NULL);
174
gpsResList = IMG_NULL;
179
PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc,
180
PRESMAN_CONTEXT *phResManContext)
183
PRESMAN_CONTEXT psResManContext;
192
eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psResManContext),
193
(IMG_VOID **)&psResManContext, IMG_NULL,
194
"Resource Manager Context");
195
if (eError != PVRSRV_OK)
197
PVR_DPF((PVR_DBG_ERROR, "PVRSRVResManConnect: ERROR allocating new RESMAN context struct"));
209
psResManContext->ui32Signature = RESMAN_SIGNATURE;
211
psResManContext->psResItemList = IMG_NULL;
212
psResManContext->psPerProc = hPerProc;
215
List_RESMAN_CONTEXT_Insert(&gpsResList->psContextList, psResManContext);
223
*phResManContext = psResManContext;
229
IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT psResManContext,
230
IMG_BOOL bKernelContext)
239
PRINT_RESLIST(gpsResList, psResManContext, IMG_TRUE);
246
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_OS_USERMODE_MAPPING, 0, 0, IMG_TRUE);
249
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DMA_CLIENT_FIFO_DATA, 0, 0, IMG_TRUE);
252
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_EVENT_OBJECT, 0, 0, IMG_TRUE);
256
List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList);
257
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_MODIFY_SYNC_OPS, 0, 0, IMG_TRUE);
258
List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList);
261
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_RENDER_CONTEXT, 0, 0, IMG_TRUE);
262
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
263
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_2D_CONTEXT, 0, 0, IMG_TRUE);
264
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
265
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, 0, 0, IMG_TRUE);
266
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC, 0, 0, IMG_TRUE);
271
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SYNC_INFO, 0, 0, IMG_TRUE);
272
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICECLASSMEM_MAPPING, 0, 0, IMG_TRUE);
273
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_WRAP, 0, 0, IMG_TRUE);
274
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_MAPPING, 0, 0, IMG_TRUE);
275
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
276
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
277
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_CONTEXT, 0, 0, IMG_TRUE);
278
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_MEM_INFO, 0, 0, IMG_TRUE);
281
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, 0, 0, IMG_TRUE);
282
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_DEVICE, 0, 0, IMG_TRUE);
285
FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_BUFFERCLASS_DEVICE, 0, 0, IMG_TRUE);
289
PVR_ASSERT(psResManContext->psResItemList == IMG_NULL);
292
List_RESMAN_CONTEXT_Remove(psResManContext);
295
OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_CONTEXT), psResManContext, IMG_NULL);
303
PRINT_RESLIST(gpsResList, psResManContext, IMG_FALSE);
310
PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT psResManContext,
311
IMG_UINT32 ui32ResType,
313
IMG_UINT32 ui32Param,
314
RESMAN_FREE_FN pfnFreeResource)
316
PRESMAN_ITEM psNewResItem;
318
PVR_ASSERT(psResManContext != IMG_NULL);
319
PVR_ASSERT(ui32ResType != 0);
321
if (psResManContext == IMG_NULL)
323
PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: invalid parameter - psResManContext"));
324
return (PRESMAN_ITEM) IMG_NULL;
333
PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: register resource "
334
"Context 0x%x, ResType 0x%x, pvParam 0x%x, ui32Param 0x%x, "
336
(IMG_UINTPTR_T)psResManContext,
338
(IMG_UINTPTR_T)pvParam,
340
(IMG_UINTPTR_T)pfnFreeResource));
343
if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
344
sizeof(RESMAN_ITEM), (IMG_VOID **)&psNewResItem,
346
"Resource Manager Item") != PVRSRV_OK)
348
PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: "
349
"ERROR allocating new resource item"));
354
return((PRESMAN_ITEM)IMG_NULL);
359
psNewResItem->ui32Signature = RESMAN_SIGNATURE;
361
psNewResItem->ui32ResType = ui32ResType;
362
psNewResItem->pvParam = pvParam;
363
psNewResItem->ui32Param = ui32Param;
364
psNewResItem->pfnFreeResource = pfnFreeResource;
365
psNewResItem->ui32Flags = 0;
368
List_RESMAN_ITEM_Insert(&psResManContext->psResItemList, psNewResItem);
376
return(psNewResItem);
379
PVRSRV_ERROR ResManFreeResByPtr(RESMAN_ITEM *psResItem, IMG_BOOL bForceCleanup)
383
PVR_ASSERT(psResItem != IMG_NULL);
385
if (psResItem == IMG_NULL)
387
PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: NULL ptr - nothing to do"));
391
PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: freeing resource at %08X",
392
(IMG_UINTPTR_T)psResItem));
401
eError = FreeResourceByPtr(psResItem, IMG_TRUE, bForceCleanup);
413
PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT psResManContext,
414
IMG_UINT32 ui32SearchCriteria,
415
IMG_UINT32 ui32ResType,
417
IMG_UINT32 ui32Param)
421
PVR_ASSERT(psResManContext != IMG_NULL);
429
PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByCriteria: "
430
"Context 0x%x, Criteria 0x%x, Type 0x%x, Addr 0x%x, Param 0x%x",
431
(IMG_UINTPTR_T)psResManContext, ui32SearchCriteria, ui32ResType,
432
(IMG_UINTPTR_T)pvParam, ui32Param));
435
eError = FreeResourceByCriteria(psResManContext, ui32SearchCriteria,
436
ui32ResType, pvParam, ui32Param,
449
PVRSRV_ERROR ResManDissociateRes(RESMAN_ITEM *psResItem,
450
PRESMAN_CONTEXT psNewResManContext)
452
PVRSRV_ERROR eError = PVRSRV_OK;
454
PVR_ASSERT(psResItem != IMG_NULL);
456
if (psResItem == IMG_NULL)
458
PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: invalid parameter - psResItem"));
460
return PVRSRV_ERROR_INVALID_PARAMS;
464
PVR_ASSERT(psResItem->ui32Signature == RESMAN_SIGNATURE);
467
if (psNewResManContext != IMG_NULL)
470
List_RESMAN_ITEM_Remove(psResItem);
473
List_RESMAN_ITEM_Insert(&psNewResManContext->psResItemList, psResItem);
478
eError = FreeResourceByPtr(psResItem, IMG_FALSE, CLEANUP_WITH_POLL);
479
if(eError != PVRSRV_OK)
481
PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: failed to free resource by pointer"));
489
static IMG_BOOL ResManFindResourceByPtr_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
493
psItem = va_arg(va, RESMAN_ITEM*);
495
return (IMG_BOOL)(psCurItem == psItem);
499
IMG_INTERNAL PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT psResManContext,
502
PVRSRV_ERROR eResult;
504
PVR_ASSERT(psResManContext != IMG_NULL);
505
PVR_ASSERT(psItem != IMG_NULL);
507
if ((psItem == IMG_NULL) || (psResManContext == IMG_NULL))
509
PVR_DPF((PVR_DBG_ERROR, "ResManFindResourceByPtr: invalid parameter"));
511
return PVRSRV_ERROR_INVALID_PARAMS;
515
PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
521
PVR_DPF((PVR_DBG_MESSAGE,
522
"FindResourceByPtr: psItem=%08X, psItem->psNext=%08X",
523
(IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)psItem->psNext));
525
PVR_DPF((PVR_DBG_MESSAGE,
526
"FindResourceByPtr: Resource Ctx 0x%x, Type 0x%x, Addr 0x%x, "
527
"Param 0x%x, FnCall %08X, Flags 0x%x",
528
(IMG_UINTPTR_T)psResManContext,
530
(IMG_UINTPTR_T)psItem->pvParam,
532
(IMG_UINTPTR_T)psItem->pfnFreeResource,
536
if(List_RESMAN_ITEM_IMG_BOOL_Any_va(psResManContext->psResItemList,
537
&ResManFindResourceByPtr_AnyVaCb,
544
eResult = PVRSRV_ERROR_NOT_OWNER;
553
static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem,
554
IMG_BOOL bExecuteCallback,
555
IMG_BOOL bForceCleanup)
557
PVRSRV_ERROR eError = PVRSRV_OK;
559
PVR_ASSERT(psItem != IMG_NULL);
561
if (psItem == IMG_NULL)
563
PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: invalid parameter"));
564
return PVRSRV_ERROR_INVALID_PARAMS;
568
PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
571
PVR_DPF((PVR_DBG_MESSAGE,
572
"FreeResourceByPtr: psItem=%08X, psItem->psNext=%08X",
573
(IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)psItem->psNext));
575
PVR_DPF((PVR_DBG_MESSAGE,
576
"FreeResourceByPtr: Type 0x%x, Addr 0x%x, "
577
"Param 0x%x, FnCall %08X, Flags 0x%x",
579
(IMG_UINTPTR_T)psItem->pvParam, psItem->ui32Param,
580
(IMG_UINTPTR_T)psItem->pfnFreeResource, psItem->ui32Flags));
583
List_RESMAN_ITEM_Remove(psItem);
590
if (bExecuteCallback)
592
eError = psItem->pfnFreeResource(psItem->pvParam, psItem->ui32Param, bForceCleanup);
593
if (eError != PVRSRV_OK)
595
PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR calling FreeResource function"));
603
OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL);
608
static IMG_VOID* FreeResourceByCriteria_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
610
IMG_UINT32 ui32SearchCriteria;
611
IMG_UINT32 ui32ResType;
613
IMG_UINT32 ui32Param;
615
ui32SearchCriteria = va_arg(va, IMG_UINT32);
616
ui32ResType = va_arg(va, IMG_UINT32);
617
pvParam = va_arg(va, IMG_PVOID);
618
ui32Param = va_arg(va, IMG_UINT32);
623
(((ui32SearchCriteria & RESMAN_CRITERIA_RESTYPE) == 0UL) ||
624
(psCurItem->ui32ResType == ui32ResType))
627
(((ui32SearchCriteria & RESMAN_CRITERIA_PVOID_PARAM) == 0UL) ||
628
(psCurItem->pvParam == pvParam))
631
(((ui32SearchCriteria & RESMAN_CRITERIA_UI32_PARAM) == 0UL) ||
632
(psCurItem->ui32Param == ui32Param))
643
static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psResManContext,
644
IMG_UINT32 ui32SearchCriteria,
645
IMG_UINT32 ui32ResType,
647
IMG_UINT32 ui32Param,
648
IMG_BOOL bExecuteCallback)
650
PRESMAN_ITEM psCurItem;
651
PVRSRV_ERROR eError = PVRSRV_OK;
655
while((psCurItem = (PRESMAN_ITEM)
656
List_RESMAN_ITEM_Any_va(psResManContext->psResItemList,
657
&FreeResourceByCriteria_AnyVaCb,
661
ui32Param)) != IMG_NULL
662
&& eError == PVRSRV_OK)
664
eError = FreeResourceByPtr(psCurItem, bExecuteCallback, CLEANUP_WITH_POLL);
672
static IMG_VOID ValidateResList(PRESMAN_LIST psResList)
674
PRESMAN_ITEM psCurItem, *ppsThisItem;
675
PRESMAN_CONTEXT psCurContext, *ppsThisContext;
678
if (psResList == IMG_NULL)
680
PVR_DPF((PVR_DBG_MESSAGE, "ValidateResList: resman not initialised yet"));
684
psCurContext = psResList->psContextList;
685
ppsThisContext = &psResList->psContextList;
688
while(psCurContext != IMG_NULL)
691
PVR_ASSERT(psCurContext->ui32Signature == RESMAN_SIGNATURE);
692
if (psCurContext->ppsThis != ppsThisContext)
694
PVR_DPF((PVR_DBG_WARNING,
695
"psCC=%08X psCC->ppsThis=%08X psCC->psNext=%08X ppsTC=%08X",
696
(IMG_UINTPTR_T)psCurContext,
697
(IMG_UINTPTR_T)psCurContext->ppsThis,
698
(IMG_UINTPTR_T)psCurContext->psNext,
699
(IMG_UINTPTR_T)ppsThisContext));
700
PVR_ASSERT(psCurContext->ppsThis == ppsThisContext);
704
psCurItem = psCurContext->psResItemList;
705
ppsThisItem = &psCurContext->psResItemList;
706
while(psCurItem != IMG_NULL)
709
PVR_ASSERT(psCurItem->ui32Signature == RESMAN_SIGNATURE);
710
if (psCurItem->ppsThis != ppsThisItem)
712
PVR_DPF((PVR_DBG_WARNING,
713
"psCurItem=%08X psCurItem->ppsThis=%08X psCurItem->psNext=%08X ppsThisItem=%08X",
714
(IMG_UINTPTR_T)psCurItem,
715
(IMG_UINTPTR_T)psCurItem->ppsThis,
716
(IMG_UINTPTR_T)psCurItem->psNext,
717
(IMG_UINTPTR_T)ppsThisItem));
718
PVR_ASSERT(psCurItem->ppsThis == ppsThisItem);
722
ppsThisItem = &psCurItem->psNext;
723
psCurItem = psCurItem->psNext;
727
ppsThisContext = &psCurContext->psNext;
728
psCurContext = psCurContext->psNext;