]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/drv/bcp/test/k2l/c66/bios/test_osal.c
bcp-lld: add to PDK
[processor-sdk/pdk.git] / packages / ti / drv / bcp / test / k2l / c66 / bios / test_osal.c
1 /**\r
2  *   @file  test_osal.c\r
3  *\r
4  *   @brief   \r
5  *      This is a sample OS Abstraction Layer (AL) file implemented\r
6  *      using XDC/BIOS APIs.\r
7  *\r
8  *      System integrator is advised to review these implementations and\r
9  *      modify them to suit it to application requirements.\r
10  *\r
11  *      This OSAL implementation uses the <b> Approach 2 </b> documented.\r
12  *\r
13  *  \par\r
14  *  ============================================================================\r
15  *  @n   (C) Copyright 2010, Texas Instruments, Inc.\r
16  * \r
17  *  Redistribution and use in source and binary forms, with or without \r
18  *  modification, are permitted provided that the following conditions \r
19  *  are met:\r
20  *\r
21  *    Redistributions of source code must retain the above copyright \r
22  *    notice, this list of conditions and the following disclaimer.\r
23  *\r
24  *    Redistributions in binary form must reproduce the above copyright\r
25  *    notice, this list of conditions and the following disclaimer in the \r
26  *    documentation and/or other materials provided with the   \r
27  *    distribution.\r
28  *\r
29  *    Neither the name of Texas Instruments Incorporated nor the names of\r
30  *    its contributors may be used to endorse or promote products derived\r
31  *    from this software without specific prior written permission.\r
32  *\r
33  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
34  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
35  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
36  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
37  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
38  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
39  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
40  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
41  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
42  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
43  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
44  *\r
45 */\r
46 /* Standard C-native includes  */\r
47 #include <stdlib.h>\r
48 #include <string.h>\r
49 \r
50 /* XDC/BIOS includes */\r
51 #include <xdc/std.h>\r
52 #include <xdc/runtime/IHeap.h>\r
53 #include <xdc/runtime/System.h>\r
54 #include <xdc/runtime/Memory.h>\r
55 #include <xdc/runtime/Error.h>\r
56 \r
57 #include <ti/sysbios/BIOS.h>\r
58 #include <ti/sysbios/hal/Hwi.h>\r
59 #include <ti/sysbios/knl/Task.h>\r
60 #include <ti/sysbios/heaps/HeapBuf.h>\r
61 #include <ti/sysbios/heaps/HeapMem.h>\r
62 \r
63 #include <xdc/cfg/global.h>\r
64 \r
65 /* IPC includes */ \r
66 #include <ti/ipc/GateMP.h>\r
67 #include <ti/ipc/Ipc.h>\r
68 #include <ti/ipc/ListMP.h>\r
69 #include <ti/ipc/SharedRegion.h>\r
70 \r
71 /* CSL CHIP, SEM Functional layer includes */\r
72 #include <ti/csl/csl_chip.h>\r
73 #include <ti/csl/csl_chipAux.h>\r
74 #include <ti/csl/csl_semAux.h>\r
75 \r
76 /* CSL Cache module includes */\r
77 #include <ti/csl/csl_cache.h>\r
78 #include <ti/csl/csl_cacheAux.h>\r
79 \r
80 /* CSL XMC includes */\r
81 #include <ti/csl/csl_xmc.h>\r
82 #include <ti/csl/csl_xmcAux.h>\r
83 \r
84 /* BCP Test application OSAL include */\r
85 #include <bcp_osal.h>\r
86 \r
87 /**********************************************************************\r
88  ****************************** Defines *******************************\r
89  **********************************************************************/\r
90 \r
91 /* Number of cores on c6498 */\r
92 #define     NUM_CORES           4\r
93 \r
94 /* Hardware Semaphore to synchronize access from\r
95  * multiple BCP applications across different cores to\r
96  * the BCP driver.\r
97  */\r
98 #define     BCP_HW_SEM          2 \r
99 \r
100 /* Hardware Semaphore to synchronize access from\r
101  * multiple applications (BCP applications and non-BCP applications)\r
102  * across different cores to the QMSS library.\r
103  */\r
104 #define     QMSS_HW_SEM         3 \r
105 \r
106 /* Hardware Semaphore to synchronize access from\r
107  * multiple applications (BCP applications and non-BCP applications)\r
108  * across different cores to the CPPI library.\r
109  */\r
110 #define     CPPI_HW_SEM         4 \r
111 \r
112 /* Hardware Semaphore to synchronize access from\r
113  * multiple applications (BCP applications and non-BCP applications)\r
114  * across different cores to the SRIO library.\r
115  */\r
116 #define     SRIO_HW_SEM         5\r
117 \r
118 /* Hardware Semaphore to synchronize access from\r
119  * multiple applications (BCP applications and non-BCP applications)\r
120  * for accumulator queues across different cores to the QMSS library.\r
121  */\r
122 #define     QMSS_ACC_HW_SEM     6\r
123  \r
124 /**********************************************************************\r
125  ************************** Global Variables **************************\r
126  **********************************************************************/\r
127 UInt32      bcpMallocCounter       =   0;\r
128 UInt32      bcpFreeCounter         =   0;\r
129 UInt32      bcpCppiMallocCounter   =   0;\r
130 UInt32      bcpCppiFreeCounter     =   0;\r
131 UInt32      bcpQmssMallocCounter   =   0;\r
132 UInt32      bcpQmssFreeCounter     =   0;\r
133 UInt32      bcpSrioMallocCounter   =   0;\r
134 UInt32      bcpSrioFreeCounter     =   0;\r
135 \r
136 UInt32      coreKey [NUM_CORES];\r
137 \r
138 #undef          BCP_TEST_DEBUG\r
139 \r
140 /**********************************************************************\r
141  *********************** BCP OSAL Functions **************************\r
142  **********************************************************************/\r
143 \r
144 /**\r
145  * ============================================================================\r
146  *  @n@b Osal_bcpLocal2Global\r
147  *\r
148  *  @b  brief\r
149  *  @n  Utility function which converts a core local address to a global\r
150  *      address.\r
151  *\r
152  *  @param[in]  addr\r
153  *      Local address to be converted\r
154  *\r
155  *  @return\r
156  *      Global Address\r
157  * =============================================================================\r
158  */\r
159 static UInt32 Osal_bcpLocal2Global (UInt32 addr)\r
160 {\r
161     UInt32 corenum;\r
162 \r
163     /* Get the core number. */\r
164     corenum = CSL_chipReadDNUM (); \r
165 \r
166     /* Compute the global address. */\r
167     return ((1 << 28) | (corenum << 24) | (addr & 0x00ffffff));\r
168 }\r
169 \r
170 /**\r
171  * ============================================================================\r
172  *  @n@b Osal_bcpGlobal2Local\r
173  *\r
174  *  @b  brief\r
175  *  @n  Utility function which converts a global to core local address.\r
176  *\r
177  *  @param[in]  gaddr\r
178  *      Global address to be converted\r
179  *\r
180  *  @return\r
181  *      Local Address\r
182  * =============================================================================\r
183  */\r
184 static UInt32 Osal_bcpGlobal2Local (UInt32 gaddr)\r
185 {\r
186     UInt32 corenum;\r
187 \r
188     /* Get the core number. */\r
189     corenum = CSL_chipReadDNUM ();\r
190 \r
191     /* Compute the global address. */\r
192     return (gaddr & ~((1 << 28) | (corenum << 24)));    \r
193 }\r
194 \r
195 /**\r
196  * ============================================================================\r
197  *  @n@b Osal_biosMalloc\r
198  *\r
199  *  @b  brief\r
200  *  @n  This API allocates a memory block of a given\r
201  *      size specified by input parameter 'num_bytes'.\r
202  *\r
203  *  @param[in]  num_bytes\r
204  *      Number of bytes to be allocated.\r
205  *\r
206  *  @param[in]  bGlobalAddress\r
207  *      Indicates whether the address returned by this API should be\r
208  *      a global address or a core local address. Global addresses are\r
209  *      required when allocating CPPI descriptors and buffers.\r
210  *\r
211  *  @return\r
212  *      Allocated block address\r
213  * =============================================================================\r
214  */\r
215 Void* Osal_biosMalloc (UInt32 num_bytes, Bool bGlobalAddress)\r
216 {\r
217         Error_Block         errorBlock;\r
218     Void*           destPtr;\r
219 \r
220     /* Increment the allocation counter. */\r
221     bcpMallocCounter++; \r
222 \r
223         /* Allocate memory from the heap */\r
224         if (destPtr = Memory_alloc(NULL, num_bytes, 0, &errorBlock))\r
225     {\r
226         /* Convert the core local address obtained from\r
227          * Memory_alloc API to a Global Address. The \r
228          * CPPI/QMSS libraries cannot handle buffers and\r
229          * descriptors that are core local addresses.\r
230          */\r
231 #ifdef BCP_TEST_DEBUG\r
232                 Bcp_osalLog ("bcpMalloc Alloc DataP: %p GlobalDataP: %p size: %d \n", destPtr, Osal_bcpLocal2Global ((UInt32) destPtr), num_bytes);         \r
233 #endif\r
234         if (bGlobalAddress)\r
235             return ((Ptr) Osal_bcpLocal2Global ((UInt32) destPtr));\r
236         else\r
237             return ((Ptr) destPtr);\r
238     }\r
239     else\r
240         return destPtr;\r
241 }\r
242 \r
243 /**\r
244  * ============================================================================\r
245  *  @n@b Osal_biosFree\r
246  *\r
247  *  @b  brief\r
248  *  @n  This API frees and restores a given memory location \r
249  *      pointer 'dataPtr' of size 'num_bytes' to its\r
250  *      original heap location.\r
251  *\r
252  *  @param[in]  dataPtr\r
253  *      Pointer to the memory block to be cleaned up.\r
254  *\r
255  *  @param[in]  num_bytes\r
256  *      Size of the memory block to be cleaned up.\r
257  *\r
258  *  @param[in]  bGlobalAddress\r
259  *      Indicates that the address passed here to this function is \r
260  *      a Global address.\r
261  *\r
262  *  @return\r
263  *      Not Applicable\r
264  * =============================================================================\r
265  */\r
266 Void Osal_biosFree (Void* dataPtr, UInt32 num_bytes, Bool bGlobalAddress)\r
267 {\r
268     /* Increment the free counter. */\r
269     bcpFreeCounter++;   \r
270 \r
271     /* Free up the memory */\r
272     if (dataPtr)\r
273     {\r
274         /* Convert the global address to local address since\r
275          * thats what the heap understands.\r
276          */\r
277 #ifdef BCP_TEST_DEBUG\r
278          Bcp_osalLog ("BcpFree DataP: %p GDP: %p size: %d\n", dataPtr, (UInt32)Osal_bcpGlobal2Local ((UInt32) dataPtr), num_bytes);\r
279 #endif\r
280          if (bGlobalAddress)\r
281             Memory_free(NULL, (Ptr) Osal_bcpGlobal2Local ((UInt32) dataPtr), num_bytes);\r
282          else\r
283             Memory_free(NULL, (Ptr) dataPtr, num_bytes);\r
284     }\r
285 }\r
286 \r
287 /**\r
288  * ============================================================================\r
289  *  @n@b Osal_biosMultiCoreCsEnter\r
290  *\r
291  *  @b  brief\r
292  *  @n  This API ensures multi-core synchronization to the caller.\r
293  *\r
294  *      This is a BLOCKING API.\r
295  *\r
296  *      This API ensures multi-core synchronization between\r
297  *      multiple processes trying to access BCP shared\r
298  *      library at the same time.\r
299  *\r
300  *  @param[in]  None\r
301  *\r
302  *  @return     None\r
303  * =============================================================================\r
304  */\r
305 Void Osal_biosMultiCoreCsEnter ()\r
306 {\r
307     /* Get the hardware semaphore. \r
308      *\r
309      * Acquire Multi core synchronization lock \r
310      */\r
311     while ((CSL_semAcquireDirect (BCP_HW_SEM)) == 0);\r
312 \r
313     return;\r
314 }\r
315 \r
316 /**\r
317  * ============================================================================\r
318  *  @n@b Osal_biosMultiCoreCsExit\r
319  *\r
320  *  @b  brief\r
321  *  @n  This API needs to be called to exit a previously\r
322  *      acquired critical section lock using @a Osal_biosMultiCoreCsEnter ()\r
323  *      API. It resets the multi-core lock, enabling another process/core \r
324  *      to grab it.\r
325  *\r
326  *  @param[in]  None\r
327  *\r
328  *  @return     None\r
329  * =============================================================================\r
330  */\r
331 Void Osal_biosMultiCoreCsExit ()\r
332 {\r
333     /* Release the hardware semaphore \r
334      *\r
335      * Release multi-core lock.\r
336      */ \r
337     CSL_semReleaseSemaphore (BCP_HW_SEM);\r
338 \r
339     return;\r
340 }\r
341 \r
342 /**\r
343  * ============================================================================\r
344  *  @n@b Osal_biosInterruptCsEnter\r
345  *\r
346  *  @b  brief\r
347  *  @n  This API ensures protection against interrupts to the caller. It prevents\r
348  *      the caller from switching to interrupt context from the application \r
349  *      thread/process context.\r
350  *\r
351  *  @param[in]  None\r
352  *\r
353  *  @return     None\r
354  * =============================================================================\r
355  */\r
356 Void Osal_biosInterruptCsEnter ()\r
357 {\r
358     /* Disable all interrupts. \r
359      *\r
360      * Acquire interrupt lock to protect from any context switches\r
361      * from application thread/process context.\r
362      */\r
363     coreKey [CSL_chipReadDNUM ()] = Hwi_disable();\r
364 \r
365     return;\r
366 }\r
367 \r
368 /**\r
369  * ============================================================================\r
370  *  @n@b Osal_biosInterruptCsExit\r
371  *\r
372  *  @b  brief\r
373  *  @n  This API needs to be called to exit a previously\r
374  *      acquired critical section lock using @a Osal_biosInterruptCsEnter ()\r
375  *      API. It restores the saved interrupt context and enables back the\r
376  *      interrupts.\r
377  *\r
378  *  @param[in]  None\r
379  *\r
380  *  @return     None\r
381  * =============================================================================\r
382  */\r
383 Void Osal_biosInterruptCsExit ()\r
384 {\r
385     /* Enable all interrupts.\r
386      *\r
387      * Release interrupt lock.\r
388      */\r
389     Hwi_restore(coreKey [CSL_chipReadDNUM ()]);\r
390 \r
391     return;\r
392 }\r
393 \r
394 /* ============================================================================\r
395  *  @n@b Osal_bcpBeginMemAccess\r
396  *\r
397  *  @b  brief\r
398  *  @n  This function invalidates the cached copy of the memory block being\r
399  *      accessed, so as to ensure that any reads to it result in valid data\r
400  *      fetches from the actual physical memory.\r
401  *\r
402  *  @param[in]  blockPtr\r
403  *       Address of the block which is to be read\r
404  *\r
405  *  @param[in]  size\r
406  *       Size of the block to be read\r
407 \r
408  *  @retval\r
409  *      Not Applicable\r
410  * =============================================================================\r
411  */\r
412 Void Osal_bcpBeginMemAccess (Void *blockPtr, UInt32 size)\r
413 {\r
414     /* Recommended sequence for cache operations is:\r
415      *  1) Disable all interrupts\r
416      *  2) Perform the cache block operation\r
417      *  3) Wait until the cache operation is done either by polling \r
418      *     the corresponding WC register or using _mfence () \r
419      *     instruction.\r
420      *  4) Enable interrupts back.\r
421      */\r
422     /* Disable all interrupts */        \r
423     Osal_biosInterruptCsEnter ();  \r
424         \r
425     /* Invalidate L1D cache and wait until operation is complete. \r
426      * Use this approach if L2 cache is not enabled \r
427      */    \r
428     CACHE_invL1d (blockPtr, size, CACHE_FENCE_WAIT);\r
429     \r
430     /* Invalidate the prefetch buffer also. */\r
431     CSL_XMC_invalidatePrefetchBuffer();    \r
432 \r
433     /* Enable back interrupts */\r
434     Osal_biosInterruptCsExit ();\r
435 \r
436     return;\r
437 }\r
438 \r
439 /* ============================================================================\r
440  *  @n@b Osal_bcpEndMemAccess\r
441  *\r
442  *  @b  brief\r
443  *  @n  This function issues a writeback operation to ensure that the contents\r
444  *      of cached copy of the memory block are updated in the actual physical \r
445  *      memory too.\r
446  *\r
447  *  @param[in]  blockPtr\r
448  *       Address of the block which is to be read\r
449  *\r
450  *  @param[in]  size\r
451  *       Size of the block to be read\r
452 \r
453  *  @retval\r
454  *      Not Applicable\r
455  * =============================================================================\r
456  */\r
457 Void Osal_bcpEndMemAccess (Void *blockPtr, UInt32 size)\r
458 {\r
459     /* Recommended sequence for cache operations is:\r
460      *  1) Disable all interrupts\r
461      *  2) Perform the cache block operation\r
462      *  3) Wait until the cache operation is done either by polling \r
463      *     the corresponding WC register or using _mfence () \r
464      *     instruction.\r
465      *  4) Enable interrupts back.\r
466      */\r
467     /* Disable all interrupts */        \r
468     Osal_biosInterruptCsEnter ();\r
469         \r
470     /* Writeback L1D cache and wait until operation is complete. \r
471      * Use this approach if L2 cache is not enabled \r
472      */    \r
473     CACHE_wbL1d (blockPtr, size, CACHE_FENCE_WAIT);\r
474 \r
475     /* Enable back interrupts */\r
476     Osal_biosInterruptCsExit ();\r
477 \r
478     return;\r
479 }\r
480 \r
481 /* ============================================================================\r
482  *  @n@b Osal_bcpBeginDescMemAccess\r
483  *\r
484  *  @b  brief\r
485  *  @n  This function invalidates the cached copy of the descriptor \r
486  *      being accessed, so as to ensure that any reads to it result in valid data\r
487  *      fetches from the actual physical memory.\r
488  *\r
489  *  @param[in]  hRx\r
490  *       Rx object handle to identify the size of descriptor correctly since \r
491  *       descriptors are allocated and managed entirely by the application.\r
492  *\r
493  *  @param[in]  descPtr\r
494  *       Descriptor address which is to be read\r
495  *\r
496  *  @retval\r
497  *      Not Applicable\r
498  * =============================================================================\r
499  */\r
500 Void Osal_bcpBeginDescMemAccess (Void* hRx, Void *descPtr)\r
501 {\r
502     /* Descriptors in the test program are allocated by default from LL2 and the \r
503      * L2 cache is disabled by default. Hence, no cache synchronization is needed\r
504      * here. This hook needs a valid implementation if descriptors are placed in\r
505      * cacheable memory region. */\r
506     return;\r
507 }\r
508 \r
509 /**********************************************************************\r
510  *********************** CPPI OSAL Functions **************************\r
511  **********************************************************************/\r
512 \r
513 /**\r
514  * ============================================================================\r
515  *  @n@b Osal_cppiCsEnter\r
516  *\r
517  *  @b  brief\r
518  *  @n  This API ensures multi-core and multi-threaded\r
519  *      synchronization to the caller.\r
520  *\r
521  *      This is a BLOCKING API.\r
522  *\r
523  *      This API ensures multi-core synchronization between\r
524  *      multiple processes trying to access CPPI shared\r
525  *      library at the same time.\r
526  *\r
527  *  @param[in]  \r
528  *  @n  None\r
529  *\r
530  *  @return     \r
531  *  @n  Handle used to lock critical section\r
532  * =============================================================================\r
533  */\r
534 Void* Osal_cppiCsEnter (Void)\r
535 {\r
536     /* Get the hardware semaphore. \r
537      *\r
538      * Acquire Multi core CPPI synchronization lock \r
539      */\r
540     while ((CSL_semAcquireDirect (CPPI_HW_SEM)) == 0);\r
541 \r
542     /* Disable all interrupts and OS scheduler. \r
543      *\r
544      * Acquire Multi threaded / process synchronization lock.\r
545      */\r
546     coreKey [CSL_chipReadDNUM ()] = Hwi_disable();\r
547 \r
548     return NULL;\r
549 }\r
550 \r
551 /**\r
552  * ============================================================================\r
553  *  @n@b Osal_cppiCsExit\r
554  *\r
555  *  @b  brief\r
556  *  @n  This API needs to be called to exit a previously\r
557  *      acquired critical section lock using @a Osal_cppiCsEnter ()\r
558  *      API. It resets the multi-core and multi-threaded lock,\r
559  *      enabling another process/core to grab CPPI access.\r
560  *\r
561  *  @param[in]  CsHandle\r
562  *      Handle for unlocking critical section.\r
563  *\r
564  *  @return     None\r
565  * =============================================================================\r
566  */\r
567 Void Osal_cppiCsExit (Void* CsHandle)\r
568 {\r
569     /* Enable all interrupts and enables the OS scheduler back on.\r
570      *\r
571      * Release multi-threaded / multi-process lock on this core.\r
572      */\r
573     Hwi_restore(coreKey [CSL_chipReadDNUM ()]);\r
574 \r
575     /* Release the hardware semaphore \r
576      *\r
577      * Release multi-core lock.\r
578      */ \r
579     CSL_semReleaseSemaphore (CPPI_HW_SEM);\r
580 \r
581     return;\r
582 }\r
583 \r
584 /**\r
585  * ============================================================================\r
586  *  @n@b Osal_cppiMalloc\r
587  *\r
588  *  @b  brief\r
589  *  @n  This API allocates a memory block of a given\r
590  *      size specified by input parameter 'num_bytes'.\r
591  *\r
592  *      This API should allocate memory from shared memory if the test applications\r
593  *      are to be run on multiple cores.\r
594  *\r
595  *  @param[in]  num_bytes\r
596  *      Number of bytes to be allocated.\r
597  *\r
598  *  @return\r
599  *      Allocated block address\r
600  * =============================================================================\r
601  */\r
602 Void* Osal_cppiMalloc (UInt32 num_bytes)\r
603 {\r
604         Error_Block         errorBlock;\r
605     Void*           dataPtr;\r
606 \r
607     /* Increment the allocation counter. */\r
608     bcpCppiMallocCounter++;     \r
609 \r
610     /* Allocate a buffer from the default HeapMemMp */\r
611     if (SharedRegion_getHeap(0) != NULL)\r
612     {\r
613         dataPtr = Memory_alloc ((xdc_runtime_IHeap_Handle) SharedRegion_getHeap(0), num_bytes, 0, &errorBlock);\r
614     }\r
615     else\r
616     {\r
617 #ifdef BCP_TEST_DEBUG           \r
618                 Bcp_osalLog ("CppiAlloc Failed for size: %d \n", num_bytes);  \r
619 #endif  \r
620         return NULL;\r
621     }\r
622 \r
623 #ifdef BCP_TEST_DEBUG\r
624     Bcp_osalLog ("CppiAlloc DataP: %p size: %d \n", dataPtr, num_bytes);\r
625 #endif        \r
626 \r
627     return dataPtr;\r
628 }\r
629 \r
630 /**\r
631  * ============================================================================\r
632  *  @n@b Osal_cppiFree\r
633  *\r
634  *  @b  brief\r
635  *  @n  This API frees and restores a given memory location \r
636  *      pointer 'dataPtr' of size 'num_bytes' to its\r
637  *      original heap location. Frees up memory allocated using \r
638  *      @a Osal_cppiMalloc ()\r
639  *\r
640  *  @param[in]  dataPtr\r
641  *      Pointer to the memory block to be cleaned up.\r
642  *\r
643  *  @param[in]  num_bytes\r
644  *      Size of the memory block to be cleaned up.\r
645  *\r
646  *  @return\r
647  *      Not Applicable\r
648  * =============================================================================\r
649  */\r
650 Void Osal_cppiFree (Void* dataPtr, UInt32 num_bytes)\r
651 {\r
652     /* Increment the free counter. */\r
653     bcpCppiFreeCounter++;       \r
654 \r
655     /* Free up the memory */\r
656     if (dataPtr)\r
657     {\r
658 #ifdef BCP_TEST_DEBUG         \r
659         Bcp_osalLog ("CppiFree: DataP: %p size: %d\n", dataPtr, num_bytes);\r
660 #endif\r
661         Memory_free ((xdc_runtime_IHeap_Handle) SharedRegion_getHeap(0), dataPtr, num_bytes);\r
662     }\r
663 }\r
664 \r
665 #if 0\r
666 Void Osal_cppiLog( String fmt, ... ) \r
667 {\r
668 }\r
669 #endif\r
670 \r
671 /**\r
672  * ============================================================================\r
673  *  @n@b Osal_cppiBeginMemAccess\r
674  *\r
675  *  @b  brief\r
676  *  @n  The function is used to indicate that a block of memory is \r
677  *      about to be accessed. If the memory block is cached then this \r
678  *      indicates that the application would need to ensure that the \r
679  *      cache is updated with the data from the actual memory.\r
680  *\r
681  *  @param[in]  ptr\r
682  *       Address of memory block\r
683  *\r
684  *  @param[in]  size\r
685  *       Size of memory block\r
686 \r
687  *  @retval\r
688  *      Not Applicable\r
689  * =============================================================================\r
690  */\r
691 void Osal_cppiBeginMemAccess (void *ptr, uint32_t size)\r
692 {\r
693     /* Recommended sequence for cache operations is:\r
694      *  1) Disable all interrupts\r
695      *  2) Perform the cache block operation\r
696      *  3) Wait until the cache operation is done either by polling \r
697      *     the corresponding WC register or using _mfence () \r
698      *     instruction.\r
699      *  4) Enable interrupts back.\r
700      */\r
701     /* Disable all interrupts */        \r
702     Osal_biosInterruptCsEnter ();  \r
703         \r
704     /* Invalidate L1D cache and wait until operation is complete. \r
705      * Use this approach if L2 cache is not enabled \r
706      */    \r
707     CACHE_invL1d (ptr, size, CACHE_FENCE_WAIT);\r
708     \r
709     /* Invalidate the prefetch buffer also. */\r
710     CSL_XMC_invalidatePrefetchBuffer();    \r
711 \r
712     /* Enable back interrupts */\r
713     Osal_biosInterruptCsExit ();\r
714 \r
715     return;\r
716 }\r
717 \r
718 \r
719 /**\r
720  * ============================================================================\r
721  *  @n@b Osal_cppiEndMemAccess\r
722  *\r
723  *  @b  brief\r
724  *  @n  The function is used to indicate that the block of memory has \r
725  *      finished being accessed. If the memory block is cached then the \r
726  *      application would need to ensure that the contents of the cache \r
727  *      are updated immediately to the actual memory.\r
728  *\r
729  *  @param[in]  ptr\r
730  *       Address of memory block\r
731  *\r
732  *  @param[in]  size\r
733  *       Size of memory block\r
734 \r
735  *  @retval\r
736  *      Not Applicable\r
737  * =============================================================================\r
738  */\r
739 void Osal_cppiEndMemAccess (void *ptr, uint32_t size)\r
740 {\r
741     /* Recommended sequence for cache operations is:\r
742      *  1) Disable all interrupts\r
743      *  2) Perform the cache block operation\r
744      *  3) Wait until the cache operation is done either by polling \r
745      *     the corresponding WC register or using _mfence () \r
746      *     instruction.\r
747      *  4) Enable interrupts back.\r
748      */\r
749     /* Disable all interrupts */        \r
750     Osal_biosInterruptCsEnter ();\r
751         \r
752     /* Writeback L1D cache and wait until operation is complete. \r
753      * Use this approach if L2 cache is not enabled \r
754      */    \r
755     CACHE_wbL1d (ptr, size, CACHE_FENCE_WAIT);\r
756 \r
757     /* Enable back interrupts */\r
758     Osal_biosInterruptCsExit ();\r
759 \r
760     return;\r
761 }\r
762 \r
763 /**********************************************************************\r
764  *********************** QMSS OSAL Functions **************************\r
765  **********************************************************************/\r
766 \r
767 /**\r
768  * ============================================================================\r
769  *  @n@b Osal_qmssCsEnter\r
770  *\r
771  *  @b  brief\r
772  *  @n  This API ensures multi-core and multi-threaded\r
773  *      synchronization to the caller.\r
774  *\r
775  *      This is a BLOCKING API.\r
776  *\r
777  *      This API ensures multi-core synchronization between\r
778  *      multiple processes trying to access QMSS shared\r
779  *      library at the same time.\r
780  *\r
781  *  @param[in]  None\r
782  *\r
783  *  @return     \r
784  *      Handle used to lock critical section\r
785  * =============================================================================\r
786  */\r
787 Void* Osal_qmssCsEnter (Void)\r
788 {\r
789     /* Get the hardware semaphore. \r
790      *\r
791      * Acquire Multi core QMSS synchronization lock \r
792      */\r
793     while ((CSL_semAcquireDirect (QMSS_HW_SEM)) == 0);\r
794 \r
795     /* Disable all interrupts and OS scheduler. \r
796      *\r
797      * Acquire Multi threaded / process synchronization lock.\r
798      */\r
799     coreKey [CSL_chipReadDNUM ()] = Hwi_disable();\r
800 \r
801     return NULL;\r
802 }\r
803 \r
804 /**\r
805  * ============================================================================\r
806  *  @n@b Osal_qmssCsExit\r
807  *\r
808  *  @b  brief\r
809  *  @n  This API needs to be called to exit a previously\r
810  *      acquired critical section lock using @a Osal_bcpQmssCsEnter ()\r
811  *      API. It resets the multi-core and multi-threaded lock,\r
812  *      enabling another process/core to grab QMSS access.\r
813  *\r
814  *  @param[in]  CsHandle\r
815  *      Handle for unlocking critical section.\r
816  *\r
817  *  @return     None\r
818  * =============================================================================\r
819  */\r
820 Void Osal_qmssCsExit (Void* CsHandle)\r
821 {\r
822     /* Enable all interrupts and enables the OS scheduler back on.\r
823      *\r
824      * Release multi-threaded / multi-process lock on this core.\r
825      */\r
826     Hwi_restore(coreKey [CSL_chipReadDNUM ()]);\r
827 \r
828     /* Release the hardware semaphore \r
829      *\r
830      * Release multi-core lock.\r
831      */ \r
832     CSL_semReleaseSemaphore (QMSS_HW_SEM);\r
833 \r
834     return;\r
835 }\r
836 \r
837 /**\r
838  * ============================================================================\r
839  *  @n@b Osal_qmssAccCsEnter\r
840  *\r
841  *  @b  brief\r
842  *  @n  This API ensures multi-core and multi-threaded\r
843  *      synchronization to the caller.\r
844  *\r
845  *      This is a BLOCKING API.\r
846  *\r
847  *      This API ensures multi-core synchronization between\r
848  *      multiple processes trying to access QMSS shared\r
849  *      library at the same time.\r
850  *\r
851  *  @param[in]  None\r
852  *\r
853  *  @return     \r
854  *      Handle used to lock critical section\r
855  * =============================================================================\r
856  */\r
857 Void* Osal_qmssAccCsEnter (Void)\r
858 {\r
859     /* Get the hardware semaphore. \r
860      *\r
861      * Acquire Multi core QMSS synchronization lock \r
862      */\r
863     while ((CSL_semAcquireDirect (QMSS_ACC_HW_SEM)) == 0);\r
864 \r
865     /* Disable all interrupts and OS scheduler. \r
866      *\r
867      * Acquire Multi threaded / process synchronization lock.\r
868      */\r
869     coreKey [CSL_chipReadDNUM ()] = Hwi_disable();\r
870 \r
871     return NULL;\r
872 }\r
873 \r
874 /**\r
875  * ============================================================================\r
876  *  @n@b Osal_qmssAccCsExit\r
877  *\r
878  *  @b  brief\r
879  *  @n  This API needs to be called to exit a previously\r
880  *      acquired critical section lock using @a Osal_qmssAccCsEnter ()\r
881  *      API. It resets the multi-core and multi-threaded lock,\r
882  *      enabling another process/core to grab QMSS access.\r
883  *\r
884  *  @param[in]  CsHandle\r
885  *      Handle for unlocking critical section.\r
886  *\r
887  *  @return     None\r
888  * =============================================================================\r
889  */\r
890 Void Osal_qmssAccCsExit (Void *CsHandle)\r
891 {\r
892     /* Enable all interrupts and enables the OS scheduler back on.\r
893      *\r
894      * Release multi-threaded / multi-process lock on this core.\r
895      */\r
896     Hwi_restore(coreKey [CSL_chipReadDNUM ()]);\r
897 \r
898     /* Release the hardware semaphore \r
899      *\r
900      * Release multi-core lock.\r
901      */ \r
902     CSL_semReleaseSemaphore (QMSS_ACC_HW_SEM);\r
903 \r
904     return;\r
905 }\r
906 \r
907 /**\r
908  * ============================================================================\r
909  *  @n@b Osal_qmssMtCsEnter\r
910  *\r
911  *  @b  brief\r
912  *  @n  This API ensures ONLY multi-threaded\r
913  *      synchronization to the QMSS user.\r
914  *\r
915  *      This is a BLOCKING API.\r
916  *\r
917  *  @param[in] None\r
918  *\r
919  *  @return     \r
920  *       Handle used to lock critical section\r
921  * =============================================================================\r
922  */\r
923 Void* Osal_qmssMtCsEnter (Void)\r
924 {\r
925     /* Disable all interrupts and OS scheduler. \r
926      *\r
927      * Acquire Multi threaded / process synchronization lock.\r
928      */\r
929     //coreKey [CSL_chipReadDNUM ()] = Hwi_disable();\r
930 \r
931     return NULL;\r
932 }\r
933 \r
934 /**\r
935  * ============================================================================\r
936  *  @n@b Osal_qmssMtCsExit\r
937  *\r
938  *  @b  brief\r
939  *  @n  This API needs to be called to exit a previously\r
940  *      acquired critical section lock using @a Osal_bcpQmssMtCsEnter ()\r
941  *      API. It resets the multi-threaded lock, enabling another process\r
942  *      on the current core to grab it.\r
943  *\r
944  *  @param[in]  CsHandle\r
945  *      Handle for unlocking critical section.\r
946  *\r
947  *  @return     None\r
948  * =============================================================================\r
949  */\r
950 Void Osal_qmssMtCsExit (Void* CsHandle)\r
951 {\r
952     /* Enable all interrupts and enables the OS scheduler back on.\r
953      *\r
954      * Release multi-threaded / multi-process lock on this core.\r
955      */\r
956     //Hwi_restore(coreKey [CSL_chipReadDNUM ()]);\r
957 \r
958     return;\r
959 }\r
960 \r
961 /**\r
962  * ============================================================================\r
963  *  @n@b Osal_qmssMalloc\r
964  *\r
965  *  @b  brief\r
966  *  @n  This API allocates a memory block of a given\r
967  *      size specified by input parameter 'num_bytes'.\r
968  *\r
969  *  @param[in]  num_bytes\r
970  *      Number of bytes to be allocated.\r
971  *\r
972  *  @return\r
973  *      Allocated block address\r
974  * =============================================================================\r
975  */\r
976 Void* Osal_qmssMalloc (UInt32 num_bytes)\r
977 {\r
978         Error_Block         errorBlock;\r
979     Void*           dataPtr;\r
980 \r
981     /* Increment the allocation counter. */\r
982     bcpQmssMallocCounter++;     \r
983 \r
984         /* Allocate memory.  */\r
985         dataPtr =  Memory_alloc(NULL, num_bytes, 0, &errorBlock);\r
986 \r
987 #ifdef BCP_TEST_DEBUG\r
988     Bcp_osalLog ("QmssAlloc DataP: %p size: %d \n", dataPtr, num_bytes);\r
989 #endif\r
990 \r
991     return dataPtr;\r
992 }\r
993 \r
994 /**\r
995  * ============================================================================\r
996  *  @n@b Osal_qmssFree\r
997  *\r
998  *  @b  brief\r
999  *  @n  This API frees and restores a given memory location \r
1000  *      pointer 'dataPtr' of size 'num_bytes' to its\r
1001  *      original heap location. Frees up memory allocated using \r
1002  *      @a Osal_qmssMalloc ()\r
1003  *\r
1004  *  @param[in]  dataPtr\r
1005  *      Pointer to the memory block to be cleaned up.\r
1006  *\r
1007  *  @param[in]  num_bytes\r
1008  *      Size of the memory block to be cleaned up.\r
1009  *\r
1010  *  @return\r
1011  *      Not Applicable\r
1012  * =============================================================================\r
1013  */\r
1014 Void Osal_qmssFree (Void* dataPtr, UInt32 num_bytes)\r
1015 {\r
1016     /* Increment the free counter. */\r
1017     bcpQmssFreeCounter++;       \r
1018 \r
1019     /* Free up the memory */\r
1020     if (dataPtr)\r
1021     {\r
1022         /* Convert the global address to local address since\r
1023          * thats what the heap understands.\r
1024          */\r
1025 #ifdef BCP_TEST_DEBUG\r
1026         Bcp_osalLog ("QmssFree DataP: %p size: %d\n", dataPtr, num_bytes);\r
1027 #endif\r
1028 \r
1029         Memory_free(NULL, dataPtr, num_bytes);\r
1030     }\r
1031 }\r
1032 \r
1033 /* ============================================================================\r
1034  *  @n@b Osal_qmssBeginMemAccess\r
1035  *\r
1036  *  @b  brief\r
1037  *  @n  The function is used to indicate that a block of memory is \r
1038  *      about to be accessed. If the memory block is cached then this \r
1039  *      indicates that the application would need to ensure that the \r
1040  *      cache is updated with the data from the actual memory.\r
1041  *\r
1042  *  @param[in]  ptr\r
1043  *       Address of memory block\r
1044  *\r
1045  *  @param[in]  size\r
1046  *       Size of memory block\r
1047 \r
1048  *  @retval\r
1049  *      Not Applicable\r
1050  * =============================================================================\r
1051  */\r
1052 void Osal_qmssBeginMemAccess (void *ptr, uint32_t size)\r
1053 {\r
1054     /* Recommended sequence for cache operations is:\r
1055      *  1) Disable all interrupts\r
1056      *  2) Perform the cache block operation\r
1057      *  3) Wait until the cache operation is done either by polling \r
1058      *     the corresponding WC register or using _mfence () \r
1059      *     instruction.\r
1060      *  4) Enable interrupts back.\r
1061      */\r
1062     /* Disable all interrupts */        \r
1063     Osal_biosInterruptCsEnter ();  \r
1064         \r
1065     /* Invalidate L1D cache and wait until operation is complete. \r
1066      * Use this approach if L2 cache is not enabled \r
1067      */    \r
1068     CACHE_invL1d (ptr, size, CACHE_FENCE_WAIT);\r
1069     \r
1070     /* Invalidate the prefetch buffer also. */\r
1071     CSL_XMC_invalidatePrefetchBuffer();    \r
1072 \r
1073     /* Enable back interrupts */\r
1074     Osal_biosInterruptCsExit ();\r
1075 \r
1076     return;\r
1077 }\r
1078 \r
1079 /* ============================================================================\r
1080  *  @n@b Osal_qmssEndMemAccess\r
1081  *\r
1082  *  @b  brief\r
1083  *  @n  The function is used to indicate that the block of memory has \r
1084  *      finished being accessed. If the memory block is cached then the \r
1085  *      application would need to ensure that the contents of the cache \r
1086  *      are updated immediately to the actual memory..\r
1087  *\r
1088  *  @param[in]  ptr\r
1089  *       Address of memory block\r
1090  *\r
1091  *  @param[in]  size\r
1092  *       Size of memory block\r
1093 \r
1094  *  @retval\r
1095  *      Not Applicable\r
1096  * =============================================================================\r
1097  */\r
1098 void Osal_qmssEndMemAccess (void *ptr, uint32_t size)\r
1099 {\r
1100     /* Recommended sequence for cache operations is:\r
1101      *  1) Disable all interrupts\r
1102      *  2) Perform the cache block operation\r
1103      *  3) Wait until the cache operation is done either by polling \r
1104      *     the corresponding WC register or using _mfence () \r
1105      *     instruction.\r
1106      *  4) Enable interrupts back.\r
1107      */\r
1108     /* Disable all interrupts */        \r
1109     Osal_biosInterruptCsEnter ();\r
1110         \r
1111     /* Writeback L1D cache and wait until operation is complete. \r
1112      * Use this approach if L2 cache is not enabled \r
1113      */    \r
1114     CACHE_wbL1d (ptr, size, CACHE_FENCE_WAIT);\r
1115 \r
1116     /* Enable back interrupts */\r
1117     Osal_biosInterruptCsExit ();\r
1118 \r
1119     return;\r
1120 }\r
1121 \r