summaryrefslogtreecommitdiff
path: root/drivers/mxc/vpu-malone/Malone_Firmware/PAL/pal.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/vpu-malone/Malone_Firmware/PAL/pal.c')
-rwxr-xr-xdrivers/mxc/vpu-malone/Malone_Firmware/PAL/pal.c780
1 files changed, 780 insertions, 0 deletions
diff --git a/drivers/mxc/vpu-malone/Malone_Firmware/PAL/pal.c b/drivers/mxc/vpu-malone/Malone_Firmware/PAL/pal.c
new file mode 100755
index 000000000000..d75db10b5606
--- /dev/null
+++ b/drivers/mxc/vpu-malone/Malone_Firmware/PAL/pal.c
@@ -0,0 +1,780 @@
+/***************************************************
+ * Copyright (c) 2015 Amphion Semiconductor Ltd
+ * All rights reserved.
+ ****************************************************
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ ****************************************************
+ *
+ * Filename : pal.c
+ * Description : Code implementing Platform Abstraction Layer
+ *
+ * Author : Media IP FW team (Belfast)
+ *
+ ****************************************************/
+
+/////////////////////////////////////////////////////////////////////////////////
+//// Header Files
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef VPU_KERNEL_BUILD
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/errno.h>
+#include "VPU_io.h"
+#else
+#undef ARM
+#undef SUCCESS
+#include <linux/io.h>
+#include <linux/kfifo.h>
+#include <linux/kthread.h>
+
+#endif
+#include "pal.h"
+#include "VPU_regdef.h"
+#include "VPU_debug.h"
+#include "mvd.h"
+
+
+///////////////////////////////////////////////////////////////////////////////////
+//// External Function Prototypes
+///////////////////////////////////////////////////////////////////////////////////
+
+// The function declared in pal.h is set to be empty
+// and need to be defined later
+
+//volatile u_int32 guPlayerFlag[MEDIA_PLAYER_NUM_STREAMS];
+
+#ifdef VPU_KERNEL_BUILD
+extern void __iomem *vpu_base;
+#define VPU_REG_WR(reg, val) writel(val, vpu_base + reg)
+#define VPU_REG_RD(reg) readl(vpu_base + reg)
+#else
+#define VPU_REG_WR(reg, val) VpuWriteReg(reg, val)
+#define VPU_REG_RD(reg) VpuReadReg(reg)
+#endif
+
+PAL_PFNISR int_handlers[INT_ID_MAX];
+
+#ifdef ENABLE_CRIT_SECTIONS
+static int ulCriticalNesting = 0;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Assert function, implementation to be defined but we want to use this to trap logical errors
+//
+bool gbAssertExit = FALSE;
+void pal_assert_impl(u_int32 uAssertPC, u_int32 uAssertInfo)
+{
+ /* AssertInfo could be the offset address of the calling function or something else? */
+ while(gbAssertExit==FALSE)
+ {
+ /* wait to allow debug */
+ }
+}
+
+
+MEDIAIP_FW_STATUS pal_critical_section_begin ( PAL_CRIT_STATE *pState )
+{
+#ifdef ENABLE_CRIT_SECTIONS
+ //ENTER_FUNC();
+ if(ulCriticalNesting>0)
+ dprintf(LVL_FUNC, "Nested %d\n", ulCriticalNesting);
+ // FIXME: might need MFD_HIF_MSD_REG_HOST_INTERRUPT_ENABLE 0x1000
+ *pState = VPU_REG_RD((DEC_MFD_XREG_SLV_BASE + MFD_HIF + MFD_HIF_MSD_REG_FAST_INTERRUPT_ENABLE));
+ VPU_REG_WR((DEC_MFD_XREG_SLV_BASE + MFD_HIF + MFD_HIF_MSD_REG_FAST_INTERRUPT_ENABLE), *pState & ~0x20);
+ //dprintf(LVL_FUNC, "save to State 0x%lx, expect 0x20 outside irq or 0 inside irq\n", *pState);
+ ulCriticalNesting++;
+#endif
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_critical_section_end ( PAL_CRIT_STATE PreviousState )
+{
+#ifdef ENABLE_CRIT_SECTIONS
+ ulCriticalNesting--;
+ //ENTER_FUNC();
+ //dprintf(LVL_FUNC, "Nest %d\n", ulCriticalNesting);
+ //dprintf(LVL_FUNC, "restore from State 0x%lx, expect 0x20 outside irq or 0 inside irq\n", PreviousState);
+ VPU_REG_WR((DEC_MFD_XREG_SLV_BASE + MFD_HIF + MFD_HIF_MSD_REG_FAST_INTERRUPT_ENABLE), PreviousState);
+#endif
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_int_register ( u_int32 dwIntID,
+ PAL_PFNISR pfnHandler,
+ BOOL bFIQ )
+{
+ ENTER_FUNC();
+ if (pfnHandler == NULL)
+ return MEDIAIP_FW_STATUS_BAD_PARAMETER;
+
+ if (dwIntID == PAL_IRQ_MALONE0_LOW) {
+ int_handlers[INT_ID_MALONE_LOW] = pfnHandler;
+ } else if (dwIntID == PAL_IRQ_MALONE0_HI) {
+ int_handlers[INT_ID_MALONE_HI] = pfnHandler;
+ } else {
+ err_msg("wrong dwIntID 0x%x\n", dwIntID);
+ return MEDIAIP_FW_STATUS_INT_NOT_HANDLED;
+ }
+ dprintf(LVL_FUNC, "pal pfnHandler 0x%p\n", pfnHandler);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+
+MEDIAIP_FW_STATUS pal_int_enable ( u_int32 dwIntID )
+{
+ ENTER_FUNC();
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+void pal_int_set ( u_int32 dwIntID )
+{
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "dwIntID %d\n", dwIntID);
+
+ if (dwIntID != PAL_IRQ_MALONE0_LOW) {
+ err_msg("ERROR: not PAL_IRQ_MALONE0_LOW!!!\n");
+ EXIT_FUNC();
+ return;
+ }
+
+ VPU_REG_WR((DEC_MFD_XREG_SLV_BASE + MFD_SIF + MFD_SIF_INTR_FORCE), 0x100);
+
+ EXIT_FUNC();
+}
+
+void pal_int_clear ( u_int32 dwIntID,
+ BOOL bDirect )
+{
+ ENTER_FUNC();
+}
+
+MEDIAIP_FW_STATUS pal_int_get_irq_line ( u_int32 uFWIrq,
+ u_int32 *puIrqLine )
+{
+ ENTER_FUNC();
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_memcpy ( void *pDest,
+ const void *pSrc,
+ u_int32 uSize )
+{
+ ENTER_FUNC();
+ if (pDest == NULL || pSrc == NULL)
+ return MEDIAIP_FW_STATUS_BAD_PARAMETER;
+
+ memcpy(pDest, pSrc, uSize);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+void pal_memset ( void *pDest, int32 nChar, u_int32 uCount )
+{
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "pDest 0x%p, nChar %d, uCount %d\n", pDest, nChar, uCount);
+ if (pDest == NULL)
+ return;
+
+ memset(pDest, nChar, uCount);
+}
+
+BOOL pal_memcompare ( void *pArea1, void *pArea2, u_int32 uSizeInWords )
+{
+ u_int32 i;
+ u_int32 *ptr0, *ptr1;
+ u_int32 uChange;
+
+ ENTER_FUNC();
+ if (pArea1 == NULL || pArea2 == NULL)
+ return FALSE;
+
+ ptr0 = ( u_int32 * ) pArea1;
+ ptr1 = ( u_int32 * ) pArea2;
+
+ for ( i = 0, uChange = 0; ( i < uSizeInWords ) && ( uChange == 0 ); i++ )
+ {
+ if ( ptr0[i] != ptr1[i] )
+ {
+ uChange = 1;
+ }
+ }
+
+ return ( uChange ) ? TRUE : FALSE;
+}
+
+MEDIAIP_FW_STATUS pal_timer_create ( PAL_PFNTIMER pfnCallback,
+ void * pUserData,
+ PAL_TIMER_ID * pTimer )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_timer_destroy( PAL_TIMER_ID Timer )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: pal_memalloc //
+// //
+// DESCRIPTION: //
+// allocates size bytes and returns a pointer to the allocated memory. //
+// The memory is not cleared. //
+// //
+// INPUT PARAMETERS: //
+// uSize - Size of memory in bytes to alloc //
+// //
+// OUTPUT PARAMETERS: //
+// //
+// RETURN VALUES: //
+// //
+// NOTES: //
+// //
+// CONTEXT: //
+// This function may be called from any context //
+// //
+////////////////////////////////////////////////////////////////////////////////
+#ifndef VPU_KERNEL_BUILD
+
+void * pal_memalloc ( size_t uSize )
+{
+ void * pPtr = malloc ( uSize );
+
+ return pPtr;
+}
+#endif
+////////////////////////////////////////////////////////////////////////////////
+// FUNCTION: pal_memfree //
+// //
+// DESCRIPTION: //
+// frees the memory space pointed to by ptr, which must have been //
+// returned by a previous call to malloc(), calloc() or realloc(). //
+// Otherwise, or if free(ptr) has already been called before, undefined //
+// behaviour occurs. If ptr is NULL, no operation is performed. //
+// //
+// //
+// INPUT PARAMETERS: //
+// pPtr - Pointer to memory to free //
+// //
+// OUTPUT PARAMETERS: //
+// //
+// RETURN VALUES: //
+// //
+// NOTES: //
+// //
+// CONTEXT: //
+// This function may be called from any context //
+// //
+////////////////////////////////////////////////////////////////////////////////
+#ifndef VPU_KERNEL_BUILD
+
+void pal_memfree ( void * pPtr )
+{
+ free ( pPtr );
+}
+#endif
+u_int32 pal_find_highest_bit ( u_int32 uValue )
+{
+ u_int32 mask = 0x80000000;
+ u_int32 ret = 31;
+
+ ENTER_FUNC();
+
+ while (mask && ((uValue & mask) == 0)) {
+ mask >>= 1;
+ ret--;
+ }
+
+ return ret;
+}
+
+MEDIAIP_FW_STATUS pal_perf_counter_create ( const char * pszName,
+ PAL_PERF_ID * pPCId )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_perf_counter_destroy ( PAL_PERF_ID PCId )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_perf_counter_start ( PAL_PERF_ID PCId )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+
+MEDIAIP_FW_STATUS pal_perf_counter_pause_control ( PAL_PERF_ID PCId , bool bStartPause)
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_perf_counter_read ( PAL_PERF_ID PerfId,
+ u_int32 * puCountVal )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_reg_init ( void )
+{
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+static void mfd_clock_enable(unsigned int mask, bool bEnable)
+{
+ if (bEnable)
+ VPU_REG_WR((DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL + MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET), mask);
+ else
+ VPU_REG_WR((DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL + MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_CLR), mask);
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_common ( bool bEnable )
+{
+ ENTER_FUNC();
+ mfd_clock_enable(0x10, bEnable);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_avc ( bool bEnable )
+{
+ ENTER_FUNC();
+ mfd_clock_enable(0x1, bEnable);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_vc1 ( bool bEnable )
+{
+ ENTER_FUNC();
+ mfd_clock_enable(0x2, bEnable);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_mpg ( bool bEnable )
+{
+ ENTER_FUNC();
+ mfd_clock_enable(0x4, bEnable);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_malone_clock_enable_avs ( bool bEnable )
+{
+ ENTER_FUNC();
+ mfd_clock_enable(0x8, bEnable);
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+u_int32 pal_get_target_version ( void )
+{
+ return 0;
+}
+
+#ifndef VPU_KERNEL_BUILD
+MEDIAIP_FW_STATUS pal_get_phy_buf(psPALMemDesc pbuf)
+{
+ vpu_mem_desc mem_desc = {0};
+ int ret;
+
+ ENTER_FUNC();
+
+ mem_desc.size = pbuf->size;
+ ret = IOGetPhyMem(&mem_desc);
+ if (ret) {
+ err_msg("Unable to obtain physical mem\n");
+ return MEDIAIP_FW_STATUS_RESOURCE_ERROR;
+ }
+
+ if (IOGetVirtMem(&mem_desc) == -1) {
+ err_msg("Unable to obtain virtual mem\n");
+ IOFreePhyMem(&mem_desc);
+ return MEDIAIP_FW_STATUS_RESOURCE_ERROR;
+ }
+
+ pbuf->phy_addr = mem_desc.phy_addr;
+ pbuf->virt_addr = mem_desc.virt_uaddr;
+#ifdef USE_ION
+ pbuf->ion_buf_fd = mem_desc.ion_buf_fd;
+#endif
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_free_phy_buf(psPALMemDesc pbuf)
+{
+ vpu_mem_desc mem_desc = {0};
+
+ ENTER_FUNC();
+
+ mem_desc.size = pbuf->size;
+ mem_desc.phy_addr = pbuf->phy_addr;
+ mem_desc.virt_uaddr = pbuf->virt_addr;
+#ifdef USE_ION
+ mem_desc.ion_buf_fd = pbuf->ion_buf_fd;
+#endif
+
+ IOFreeVirtMem(&mem_desc);
+ IOFreePhyMem(&mem_desc);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+#endif
+
+u_int32 pal_va2pa ( u_int32 * pAddr )
+{
+ /* CAUTION: pAddr shall be physical address already*/
+ dprintf(LVL_FUNC, "pAddr 0x%p shall be physical!!!\n", pAddr);
+ return (u_int32)(uint_addr)pAddr;
+}
+
+u_int32 * pal_return_uncached_addr ( u_int32 * puAddress )
+{
+ dprintf(LVL_FUNC, "puAddress 0x%p\n", puAddress);
+ return puAddress;
+}
+
+u_int32 * pal_return_cacheable_addr ( u_int32 * puAddress )
+{
+ dprintf(LVL_FUNC, "puAddress 0x%p\n", puAddress);
+ return puAddress;
+}
+
+u_int32 pal_read_uncached ( u_int32 * puAddress )
+{
+ dprintf(LVL_FUNC, "puAddress 0x%p\n", puAddress);
+
+ if (puAddress == NULL)
+ return MEDIAIP_FW_STATUS_BAD_PARAMETER;
+
+ return (*puAddress);
+}
+
+int pal_vsnprintf ( char *str, int size, const char *format, va_list args )
+{
+ ENTER_FUNC();
+ return 0;
+}
+
+int pal_sprintf ( char *str, int size, const char *psz_format, ...)
+{
+ ENTER_FUNC();
+ return 0;
+}
+
+static void mfd_cache_clock_enable(unsigned int enable)
+{
+ ENTER_FUNC();
+ VPU_REG_WR((SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET),enable);
+}
+
+void pal_set_malone_cache ( u_int32 uMalID )
+{
+ ENTER_FUNC();
+ mfd_cache_clock_enable(0xE);
+}
+
+#define MAX_QUEUE_NUM 10
+static PAL_QUEUE_ID gQuId = 0;
+
+MEDIAIP_FW_STATUS pal_sem_create ( u_int32 uInitialValue,
+ const char *pszName,
+ PAL_SEM_ID *pSem)
+{
+ /* CAUTION: if in use */
+ ENTER_FUNC();
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+#ifdef VPU_KERNEL_BUILD
+
+static struct kfifo irq_fifo[MAX_QUEUE_NUM];
+static spinlock_t irq_lock[MAX_QUEUE_NUM];
+static struct task_struct *msg_thread;
+static wait_queue_head_t irq_wq[MAX_QUEUE_NUM];
+
+MEDIAIP_FW_STATUS pal_thread_create ( PAL_PFNTHREAD pfnEntryPoint,
+ int nArgC,
+ void **ppArgV,
+ u_int32 uStackSize,
+ u_int8 uPrio,
+ const char *pszName,
+ PAL_THREAD_ID *pId )
+{
+ typedef int (*INTFUNC)(void *);
+
+ /* CAUTION: shall not enter twice due to global msg_thread */
+ ENTER_FUNC();
+ //struct task_struct *msg_thread;
+ msg_thread = kthread_run((INTFUNC)pfnEntryPoint , NULL, pszName);
+ if(IS_ERR( msg_thread ))
+ return MEDIAIP_FW_STATUS_FAILURE;
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_thread_terminate ( PAL_THREAD_ID *pId )
+{
+ ENTER_FUNC();
+
+ kthread_stop(msg_thread);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_create ( unsigned int nMaxElements,
+ const char *pszName,
+ PAL_QUEUE_ID *pQuId )
+{
+ /* CAUTION: message length shall be 4 * sizeof(uint_addr) */
+ ENTER_FUNC();
+ *pQuId = gQuId;
+ spin_lock_init(&irq_lock[*pQuId]);
+ init_waitqueue_head(&irq_wq[*pQuId]);
+ if(kfifo_alloc(&irq_fifo[*pQuId],
+ nMaxElements * 4 * sizeof(uint_addr),
+ GFP_KERNEL))
+ {
+ err_msg("fail to alloc fifo in pal\n");
+ return MEDIAIP_FW_STATUS_FAILURE;
+ }
+
+ gQuId++;
+ if( MAX_QUEUE_NUM == gQuId)
+ gQuId=0;
+ dprintf(LVL_FUNC, "create QuId:%d\n",
+ *pQuId
+ );
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_destroy ( PAL_QUEUE_ID QuId )
+{
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "destory QuId:%d\n",
+ QuId
+ );
+ kfifo_free(&irq_fifo[QuId]);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_send ( PAL_QUEUE_ID QuId,
+ void *pMessage)
+{
+ u_int32 retval;
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "QuId %d\n", QuId);
+
+ /* CAUTION: if message is not 4 * sizeof(uint_addr) */
+ retval = kfifo_in_locked(&irq_fifo[QuId], pMessage, 4 * sizeof(uint_addr),&irq_lock[QuId]);
+ dprintf(LVL_FUNC, "message send: 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", *(uint_addr *)pMessage, *((uint_addr *)pMessage+1), *((uint_addr *)pMessage+2), *((uint_addr *)pMessage+3));
+ if(retval != 4*sizeof(uint_addr))
+ return MEDIAIP_FW_STATUS_FAILURE;
+ wake_up(&irq_wq[QuId]);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_receive ( PAL_QUEUE_ID QuId,
+ u_int32 uTimeoutMs,
+ void *pMessage )
+{
+ u_int32 retval;
+ long ret;
+
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "QuId %d\n", QuId);
+/* while (kfifo_len(&irq_fifo) < sizeof(*pMessage)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ }*/
+ ret = wait_event_interruptible_timeout(irq_wq[QuId],
+ kfifo_len(&irq_fifo[QuId])>=4*sizeof(uint_addr)
+ /* || kthread_should_stop() */,
+ //uTimeoutMs
+ msecs_to_jiffies(uTimeoutMs)
+ );
+
+ if (ret == 0) {
+ dprintf(LVL_FUNC, "timeout %d ms\n", uTimeoutMs);
+ return MEDIAIP_FW_STATUS_TIMEOUT;
+ } else if (ret == -ERESTARTSYS) {
+ dprintf(LVL_FUNC, "ERROR interrupted by a signal!!\n");
+ return MEDIAIP_FW_STATUS_FAILURE;
+ } else {
+ dprintf(LVL_FUNC, "%ld returned from wait event\n", ret);
+ }
+
+ //if(kthread_should_stop())
+ // return MEDIAIP_FW_STATUS_STOPPED;
+
+ if (kfifo_len(&irq_fifo[QuId])>=4*sizeof(uint_addr))
+ {
+ retval = kfifo_out_locked(&irq_fifo[QuId], pMessage, 4*sizeof(uint_addr),&irq_lock[QuId]);
+ dprintf(LVL_FUNC, "message receive: 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", *(uint_addr *)pMessage, *((uint_addr *)pMessage+1), *((uint_addr *)pMessage+2), *((uint_addr *)pMessage+3));
+ }
+ else
+ {
+ dprintf(LVL_FUNC, "ERROR interrupted by a signal!!\n");
+ }
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+#else
+
+#define FN_MSG_FIFO "/dev/shm/vpu_msg_fifo"
+static char fn_fifo[MAX_QUEUE_NUM][64] = {0};
+static int fd_send[MAX_QUEUE_NUM] = {0};
+static int fd_receive[MAX_QUEUE_NUM] = {0};
+
+MEDIAIP_FW_STATUS pal_thread_create ( PAL_PFNTHREAD pfnEntryPoint,
+ int nArgC,
+ void **ppArgV,
+ u_int32 uStackSize,
+ u_int8 uPrio,
+ const char *pszName,
+ PAL_THREAD_ID *pId )
+{
+ int err;
+ pthread_t msg_tid;
+
+ ENTER_FUNC();
+ err = pthread_create(&msg_tid, NULL, (void *)pfnEntryPoint, NULL);
+ if (err)
+ return MEDIAIP_FW_STATUS_FAILURE;
+
+ *pId = msg_tid;
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_thread_terminate ( PAL_THREAD_ID *pId )
+{
+ pthread_t msg_tid = *pId;
+
+ ENTER_FUNC();
+
+ if (msg_tid == 0)
+ return MEDIAIP_FW_STATUS_BAD_PARAMETER;
+
+ pthread_cancel(msg_tid);
+ pthread_join(msg_tid, NULL);
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_create ( unsigned int nMaxElements,
+ const char *pszName,
+ PAL_QUEUE_ID *pQuId )
+{
+ /* CAUTION: message length shall be 4 * sizeof(uint_addr) */
+ ENTER_FUNC();
+ *pQuId = gQuId;
+ sprintf(fn_fifo[gQuId], "%s%d", FN_MSG_FIFO, gQuId);
+ if(access(fn_fifo[gQuId], F_OK) == -1)
+ {
+ if(mkfifo(fn_fifo[gQuId], 0777))
+ {
+ err_msg("failed to alloc fifo %s in pal\n", fn_fifo[gQuId]);
+ return MEDIAIP_FW_STATUS_FAILURE;
+ }
+ dprintf(LVL_FUNC, "created fifo %s\n", fn_fifo[gQuId]);
+ } else {
+ dprintf(LVL_FUNC, "exist fifo %s\n", fn_fifo[gQuId]);
+ }
+
+ gQuId++;
+ if( MAX_QUEUE_NUM == gQuId)
+ gQuId=0;
+ dprintf(LVL_FUNC, "create QuId:%d\n",
+ *pQuId
+ );
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_destroy ( PAL_QUEUE_ID QuId )
+{
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "destory QuId:%d\n",
+ QuId
+ );
+ if (fd_send[QuId]) {
+ close(fd_send[QuId]);
+ fd_send[QuId] = 0;
+ }
+ if (fd_receive[QuId]) {
+ close(fd_receive[QuId]);
+ fd_receive[QuId] = 0;
+ }
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_send ( PAL_QUEUE_ID QuId,
+ void *pMessage)
+{
+ u_int32 retval;
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "QuId %d\n", QuId);
+
+ /* CAUTION: if message is not 4 * sizeof(uint_addr) */
+ if (fd_send[QuId] == 0) {
+ fd_send[QuId] = open(fn_fifo[QuId], O_WRONLY);
+ if (fd_send[QuId] == -1) {
+ err_msg("failed to open fifo %s to send\n", fn_fifo[QuId]);
+ return MEDIAIP_FW_STATUS_FAILURE;
+ } else {
+ dprintf(LVL_FUNC, "opened fifo %s to send\n", fn_fifo[QuId]);
+ }
+ }
+ retval = write(fd_send[QuId], pMessage, 4 * sizeof(uint_addr));
+ if(retval != 4*sizeof(uint_addr))
+ {
+ err_msg("%s\n", strerror(errno));
+ return MEDIAIP_FW_STATUS_FAILURE;
+ }
+ dprintf(LVL_FUNC, "message send: 0x%lx, 0x%lx, 0x%lx, 0x%lx\n", *(uint_addr *)pMessage, *((uint_addr *)pMessage+1), *((uint_addr *)pMessage+2), *((uint_addr *)pMessage+3));
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+
+MEDIAIP_FW_STATUS pal_qu_receive ( PAL_QUEUE_ID QuId,
+ u_int32 uTimeoutMs,
+ void *pMessage )
+{
+ u_int32 retval;
+
+ ENTER_FUNC();
+ dprintf(LVL_FUNC, "QuId %d\n", QuId);
+ // TODO: time out case
+ if (fd_receive[QuId] == 0) {
+ fd_receive[QuId] = open(fn_fifo[QuId], O_RDONLY);
+ if (fd_receive[QuId] == -1) {
+ err_msg("failed to open fifo %s to receive\n", fn_fifo[QuId]);
+ return MEDIAIP_FW_STATUS_FAILURE;
+ } else {
+ dprintf(LVL_FUNC, "opened fifo %s to receive\n", fn_fifo[QuId]);
+ }
+ }
+ retval = read(fd_receive[QuId], pMessage, 4*sizeof(uint_addr));
+ if(retval != 4*sizeof(uint_addr))
+ {
+ err_msg("%s\n", strerror(errno));
+ return MEDIAIP_FW_STATUS_FAILURE;
+ }
+ dprintf(LVL_FUNC, "message receive: 0x%lx, 0x%lx, 0x%lx, 0x%lx\n", *(uint_addr *)pMessage, *((uint_addr *)pMessage+1), *((uint_addr *)pMessage+2), *((uint_addr *)pMessage+3));
+
+ return MEDIAIP_FW_STATUS_OK;
+}
+#endif
+