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