remove ducati submodule
[gstreamer-omap:ndecs-libdce.git] / memsrv.c
1 /*
2  * Copyright (c) 2010, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /* NOTE: this code should be folded into a library as part of syslink.. but
34  * for now, this ugly hack of duplicating code from syslink and domx..
35  */
36
37 /*============================================================================
38  *  @file   MemMgr.c
39  *
40  *  @brief  TILER Client Sample application for TILER module between MPU & Ducati
41  *
42  *  ============================================================================
43  */
44
45
46 /* OS-specific headers */
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <unistd.h>
50 #include <stdint.h>
51
52 #include <pthread.h>
53 #include <semaphore.h>
54 #include <signal.h>
55
56 /* Standard headers */
57 #include <Std.h>
58
59 /* OSAL & Utils headers */
60 #include <OsalPrint.h>
61 #include <String.h>
62 #include <Trace.h>
63
64 /* IPC headers */
65 #include <IpcUsr.h>
66 #include <ProcMgr.h>
67
68 /* RCM headers */
69 #include <RcmServer.h>
70
71 /* TILER headers */
72 #include <tilermgr.h>
73
74 #if defined (__cplusplus)
75 extern "C" {
76 #endif /* defined (__cplusplus) */
77
78 /** ============================================================================
79  *  Macros and types
80  *  ============================================================================
81  */
82
83 #define DIM(x) (sizeof (x) / sizeof((x)[0]))
84
85 static RcmServer_Handle rcmServerHandle;
86
87
88 /*
89  * Remote function argument structures
90  *
91  * All fields are simple UInts and Ptrs.  Some arguments may be smaller than
92  * these fields, which is okay, as long as they are correctly "unpacked" by the
93  * server.
94  */
95
96 typedef struct {
97     UInt    pixelFormat;
98     UInt    width;
99     UInt    height;
100     UInt    length;
101     UInt    stride;
102     Ptr     ptr;
103     UInt  * reserved;
104 } AllocParams;
105
106 typedef struct {
107     UInt        numBuffers;
108     AllocParams params [1];
109 } AllocArgs;
110
111 typedef struct {
112     Ptr bufPtr;
113 } FreeArgs, ConvertPageModeToTilerSpaceArgs;
114
115 typedef struct {
116     Ptr     bufPtr;
117     UInt    rotationAndMirroring;
118 } ConvertToTilerSpaceArgs;
119
120 typedef struct {
121     UInt32 code;
122 } DebugArgs;
123
124
125 typedef struct  {  /* TODO: remove */
126     enum pixel_fmt_t pixelFormat;  /* pixel format */
127     union {
128         struct {
129             pixels_t width;  /* width of 2D buffer */
130             pixels_t height; /* height of 2D buffer */
131         };
132         struct {
133             bytes_t  length;  /* length of 1D buffer.  Must be multiple of
134                                 stride if stride is not 0. */
135         };
136     };
137     unsigned long   stride;    /* must be multiple of page size.  Can be 0 only
138                                 if pixelFormat is KPAGE. */
139     void          * ptr;               /* pointer to beginning of buffer */
140     unsigned long   reserved;  /* system space address (used internally) */
141 } MemMgrBlock;
142
143 /*
144  *  ======== getAccessMode ========
145  *  helper func to determine bit mode
146  */
147 static
148 UInt getAccessMode (Ptr bufPtr)
149 {
150     UInt addr = (UInt)bufPtr;
151
152     /*
153      * The access mode decoding is as follows:
154      *
155      * 0x60000000 - 0x67FFFFFF : 8-bit
156      * 0x68000000 - 0x6FFFFFFF : 16-bit
157      * 0x70000000 - 0x77FFFFFF : 32-bit
158      * 0x77000000 - 0x7FFFFFFF : Page mode
159      */
160     switch (addr & 0xf8000000) {   /* Mask out the lower bits */
161     case 0x60000000:
162         return PIXEL_FMT_8BIT;
163     case 0x68000000:
164         return PIXEL_FMT_16BIT;
165     case 0x70000000:
166         return PIXEL_FMT_32BIT;
167     case 0x78000000:
168         return PIXEL_FMT_PAGE;
169     default:        /* TODO: How to handle invalid case? */
170         return 0;
171     }
172 }
173
174 /*
175  *  ======== getStride ========
176  *  helper func to determine stride length
177  */
178 static
179 UInt getStride (Ptr bufPtr)
180 {
181     switch (getAccessMode (bufPtr)) {
182     case PIXEL_FMT_8BIT:
183         return 0x4000;  /* 16 KB of stride */
184     case PIXEL_FMT_16BIT:
185     case PIXEL_FMT_32BIT:
186         return 0x8000;  /* 32 KB of stride */
187     default:
188         return 0;       /* Stride not applicable */
189     }
190 }
191
192 /*
193  *  ======== fxnMemMgr_Debug ========
194  *     RCM function for debugging
195 */
196 static
197 Int32 fxnMemMgr_Debug (UInt32 dataSize, UInt32 *data)
198 {
199     DebugArgs * args = (DebugArgs *)data;
200     Osal_printf ("Executing MemMgr_Debug: %08x\n", args->code);
201 }
202
203 /*
204  *  ======== fxnMemMgr_Alloc ========
205  *     RCM function for MemMgr_Alloc function
206 */
207 static
208 Int32 fxnMemMgr_Alloc (UInt32 dataSize, UInt32 *data)
209 {
210     AllocArgs     * args = (AllocArgs *)data;
211     Int             i;
212     MemMgrBlock   * params;
213     Ptr             allocedPtr;
214
215     Osal_printf ("Executing MemMgr_Alloc with params:\n");
216     Osal_printf ("\tnumBuffers = %d\n", args->numBuffers);
217     for(i = 0; i < args->numBuffers; i++) {
218         Osal_printf ("\tparams [%d].pixelFormat = %d\n", i,
219                         args->params [i].pixelFormat);
220         Osal_printf ("\tparams [%d].width = %d\n", i, args->params [i].width);
221         Osal_printf ("\tparams [%d].height = %d\n", i, args->params [i].height);
222         Osal_printf ("\tparams [%d].length = %d\n", i, args->params [i].length);
223     }
224
225     params = (MemMgrBlock *) malloc (sizeof(MemMgrBlock) * args->numBuffers);
226
227     if (params == NULL) {
228         Osal_printf ("Error allocating array of MemMgrBlock params.\n");
229         return (Int32)NULL;
230     }
231
232     for(i = 0; i < args->numBuffers; i++) {
233         params [i].pixelFormat = args->params [i].pixelFormat;
234
235         params [i].width = args->params [i].width;
236         /* TODO: provide length support on Ducati */
237         params [i].height = args->params [i].height;
238         params [i].length = args->params [i].length;
239     }
240
241     /* Allocation */
242     for (i = 0; i < args->numBuffers; i++) {
243         switch (params [i].pixelFormat) {
244         case PIXEL_FMT_8BIT:
245         case PIXEL_FMT_16BIT:
246         case PIXEL_FMT_32BIT:
247             Osal_printf ("fxnMemMgr_Alloc: calling TilerMgr_Alloc.\n");
248             args->params [i].ptr = (Ptr)TilerMgr_Alloc (params [i].pixelFormat,
249                                         params [i].width, params [i].height);
250             break;
251         case PIXEL_FMT_PAGE:
252             Osal_printf ("fxnMemMgr_Alloc: calling TilerMgr_PageModeAlloc.\n");
253             args->params [i].ptr = \
254                                 (Ptr)TilerMgr_PageModeAlloc (params [i].length);
255             break;
256         default:    /* Invalid case */
257             Osal_printf ("fxnMemMgr_Alloc: Invalid pixel format.\n");
258             args->params [i].ptr = NULL;
259             break;
260         }
261         args->params [i].stride = getStride (args->params [i].ptr);
262     }
263
264     allocedPtr = args->params [0].ptr;
265     free (params);
266
267     Osal_printf ("fxnMemMgr_Alloc done.\n");
268     return (Int32) allocedPtr; /* Return first buffer pointer */
269 }
270
271
272
273 /*
274  *  ======== fxnMemMgr_Free ========
275  *     RCM function for MemMgr_Free
276  */
277 static
278 Int32 fxnMemMgr_Free (UInt32 dataSize, UInt32 *data)
279 {
280     FreeArgs  * args    = (FreeArgs *)data;
281     UInt32      status  = 0;
282
283     Osal_printf ("Executing MemMgr_Free with params:\n");
284     Osal_printf ("\tbufPtr = 0x%x\n", args->bufPtr);
285
286     switch (getAccessMode (args->bufPtr)) {
287     case PIXEL_FMT_8BIT:
288     case PIXEL_FMT_16BIT:
289     case PIXEL_FMT_32BIT:
290         Osal_printf ("fxnMemAlloc_Free: calling TilerMgr_Free.\n");
291         status = TilerMgr_Free ((Int)args->bufPtr);
292         break;
293     case PIXEL_FMT_PAGE:
294         Osal_printf ("fxnMemAlloc_Free: calling TilerMgr_PageModeFree.\n");
295         status = TilerMgr_PageModeFree ((Int)args->bufPtr);
296         break;
297     default:    /* Invalid case */
298         Osal_printf ("fxnMemAlloc_Free: Invalid pointer.\n");
299         break;
300     }
301
302     Osal_printf ("fxnMemMgr_Free done.\n");
303     return status;
304 }
305
306 /*
307  *  ======== fxnTilerMem_ConvertToTilerSpace ========
308  *     RCM function for TilerMem_ConvertToTilerSpace
309  */
310 static
311 Int32 fxnTilerMem_ConvertToTilerSpace (UInt32 dataSize, UInt32 *data)
312 {
313     ConvertToTilerSpaceArgs   * args = (ConvertToTilerSpaceArgs *)data;
314     UInt32                      addr;
315
316     Osal_printf ("Executing TilerMem_ConvertToTilerSpace with params:\n");
317     Osal_printf ("\tbufPtr = 0x%x\n", args->bufPtr);
318     Osal_printf ("\trotationAndMirroring = 0x%x\n", args->rotationAndMirroring);
319
320     //Stubbed out pending implementation
321     /*addr = TilerMem_ConvertToTilerSpace (args->bufPtr,
322                                             args->rotationAndMirroring);*/
323     addr = TRUE;
324
325     return addr;
326 }
327
328 /*
329  *  ======== fxnTilerMem_ConvertPageModeToTilerSpace ========
330  *     RCM function for TilerMem_ConvertPageModeToTilerSpace
331  */
332 static
333 Int32 fxnTilerMem_ConvertPageModeToTilerSpace (UInt32 dataSize, UInt32 *data)
334 {
335     ConvertPageModeToTilerSpaceArgs   * args = \
336                                         (ConvertPageModeToTilerSpaceArgs *)data;
337     UInt32                              addr;
338
339     Osal_printf ("Executing TilerMem_ConvertPageModeToTilerSpace with params:");
340     Osal_printf ("\n\tbufPtr = 0x%x\n", args->bufPtr);
341
342     //Stubbed out pending implementation
343     //addr = TilerMem_ConvertPageModeToTilerSpace (args->bufPtr);
344     addr = TRUE;
345
346     return addr;
347 }
348
349 struct MemMgr_funcInfo {
350     RcmServer_MsgFxn fxnPtr;
351     String           name;
352 };
353
354 static struct MemMgr_funcInfo memMgrFxns [] =
355 {
356     { fxnMemMgr_Alloc,                        "MemMgr_Alloc"},
357     { fxnMemMgr_Free,                         "MemMgr_Free"},
358     { fxnMemMgr_Debug,                        "MemMgr_Debug"},
359     { fxnTilerMem_ConvertToTilerSpace,        "TilerMem_ConvertToTilerSpace"},
360     { fxnTilerMem_ConvertPageModeToTilerSpace,
361                                         "TilerMem_ConvertPageModeToTilerSpace"},
362 };
363
364 /*
365  *  ======== MemMgrThreadFxn ========
366  *     TILER server thread function
367  */
368
369 int
370 memsrv_init (char *name)
371 {
372     Int                 status;
373     RcmServer_Params    rcmServerParams;
374     UInt                fxnIdx;
375     Int                 i;
376
377     /* RCM Server module init */
378     Osal_printf ("RCM Server module init.\n");
379     RcmServer_init ();
380
381     /* rcm client module params init*/
382     Osal_printf ("RCM Server module params init.\n");
383     status = RcmServer_Params_init (&rcmServerParams);
384     if (status < 0) {
385         Osal_printf ("Error in RCM Server instance params init \n");
386         return status;
387     }
388
389     /* create the RcmServer instance */
390     Osal_printf ("Creating RcmServer instance: %s\n", name);
391     status = RcmServer_create (name, &rcmServerParams,
392                                 &rcmServerHandle);
393     if (status < 0) {
394         Osal_printf ("Error in RCM Server create.\n");
395         return status;
396     }
397
398     for (i = 0; i < DIM (memMgrFxns); i++) {
399         status = RcmServer_addSymbol (rcmServerHandle, memMgrFxns [i].name,
400                             memMgrFxns [i].fxnPtr, &fxnIdx);
401         /* Register the remote functions */
402         Osal_printf ("Registering remote function %s with index %d\n",
403                         memMgrFxns [i].name, fxnIdx);
404         if (status < 0) {
405             Osal_printf ("Add symbol failed with status 0x%08x.\n", status);
406             return status;
407         }
408     }
409
410     status = TilerMgr_Open ();
411     if (status < 0) {
412         Osal_printf ("Error in TilerMgr_Open: status = 0x%x\n", status);
413         return status;
414     }
415
416     Osal_printf ("Start RCM server thread \n");
417     RcmServer_start (rcmServerHandle);
418
419     Osal_printf ("\nDone initializing RCM server.  Ready to receive requests "
420                     "from Ducati.\n");
421
422     return status;
423 }
424
425 int
426 memsrv_deinit (void)
427 {
428     Int                 status;
429     Int                 i;
430
431     if (! rcmServerHandle) {
432         return 0;
433     }
434
435     for (i = 0; i < DIM (memMgrFxns); i++) {
436         /* Unregister the remote functions */
437         status = RcmServer_removeSymbol (rcmServerHandle, memMgrFxns [i].name);
438         if (status < 0) {
439             Osal_printf ("Remove symbol %s failed.\n", memMgrFxns [i].name);
440         }
441     }
442
443     status = RcmServer_delete (&rcmServerHandle);
444     if (status < 0) {
445         Osal_printf ("Error in RcmServer_delete: status = 0x%x\n", status);
446         return status;
447     }
448
449     RcmServer_exit ();
450
451     return 0;
452 }
453
454 #if defined (__cplusplus)
455 }
456 #endif /* defined (__cplusplus) */