xtask_rpc.c
来自「SigmDesign SMP8634 media decode chip dev」· C语言 代码 · 共 967 行 · 第 1/3 页
C
967 行
if( xtask_ioctl(context,procIndex,args) != RM_OK ) { err = RM_ERROR; goto safe_exit; } #ifdef USE_RPC_TIMEOUT if( args->timeout_us ) { err = xtask_rpc_wait_for_completion_wtimeout(context,args->timeout_us); if( RMFAILED(err) ) goto safe_exit; } else { /* Timeout val of (0) waits forever! */ xtask_rpc_wait_for_completion(context); }#else /* Wait for procedure to finish */ xtask_rpc_wait_for_completion(context);#endif /* Get return args and return result */ if( (err = xtask_pull_args( pgbus, context->fifo, args )) != RM_OK ) { err = RM_ERROR; goto safe_exit; } /* get the return status */ err = xtask_rpc_get_status(context); safe_exit: /* release the semaphore */ xtask_semaphore_release( context ); return err;}/**************************************************************** Method Name ** xtask_rpc_wait_for_completion ** ** Description: ** Wait until the procedure has finished. ** ****************************************************************/RMstatus xtask_rpc_wait_for_completion_wtimeout( struct XtaskAPI* context, RMuint32 timeout_us ){ struct gbus *pgbus = context->pgbus; RMuint32 startTime = timer_start(pgbus); /* Maximum timer value is 159072861 us ( 2 ^ 32 ticks / 27,000,000 ticks/second ) * The effective range provided by the rpc call is cut in half as to prevent the * chance of an infinite loop where the timer interval is not read in time before * a rollover. So the effective maximum timeout is '159072861/2' * => 79536430 us (79 seconds) * * This is much larger than what should be needed. * */ if( timeout_us > MAX_TIMEOUT ) timeout_us = MAX_TIMEOUT; while( gbus_read_uint32( pgbus, (RMuint32)&context->fifo->procedureFd) != 0 ){ if( timer_interval_complete( pgbus, startTime, timeout_us) ) { RMDBGLOG((ENABLE,"xtask rpc operation timed out!\n")); return RM_TIMEOUT; } /* Don't read GBUS too often! */ delay_us(5); } return RM_OK;}/**************************************************************** Method Name ** xtask_rpc_wait_for_completion ** ** Description: ** Wait until the procedure has finished. ** ****************************************************************/RMstatus xtask_rpc_wait_for_completion( struct XtaskAPI* context /*RMuint32 timeout_us*/ ){ struct gbus *pgbus = context->pgbus; /* TODO: Implement Timeout, by adding (int timeout) in ms to the call list. */ while( gbus_read_uint32( pgbus, (RMuint32)&context->fifo->procedureFd) != 0 ){ /* Don't read GBUS too often! */ delay_us(5); } return RM_OK;}/**************************************************************** Method Name ** xtask_rpc_sync ** ** Description: ** This procedure prevents a race condition with the ** xtask. Basically, the xtask signals it has ended ** its initialization, and ready to go by constantly ** changing an agreed upon memory location in the PID ** rpc2xtask zone. Once this procedure sees a change ** in the memory location, it signals an ack to the ** xtask by resetting a different agreed upon memory ** location. ** ****************************************************************/RMstatus xtask_rpc_sync(struct XtaskAPI* context){ RMuint32 first, second, third; struct gbus *pgbus = context->pgbus; RMuint32 xPid; RMuint32 startTime; xPid = context->xPid; RMDBGLOG((ENABLE,"Syncing to xPid %d\n",xPid)); /* DEBUG */ RMDBGLOG((LOCALDBG, "GBUS_ADDR(xPid_FIFO_SYNC) = 0x%lx\n", (RMuint32)(&context->fifo->xtaskToCPUSignal) )); /* Get initial timer value */ startTime = timer_start(pgbus); /* Remember the first value in the agreed upon memory location */ /* Added robustness: Xtask is looping on {0:255} interval only */ while((first = gbus_read_uint32(pgbus, (RMuint32)&context->fifo->xtaskToCPUSignal)) > 255 ) { RMDBGLOG((LOCALDBG, "Waiting on first == 0x%lx\n",first)); if( timer_interval_complete(pgbus, startTime, SYNC_TIMEOUT_US) ){ RMDBGLOG((ENABLE,"Sync Timeout!\n")); return RM_TIMEOUT; } } /* Wait for this value to change */ while ( ((second = gbus_read_uint32(pgbus, (RMuint32)&context->fifo->xtaskToCPUSignal)) == first) || (second>255)) { RMDBGLOG((LOCALDBG,"Waiting on second == 0x%lx\n",second)); if( timer_interval_complete(pgbus, startTime, SYNC_TIMEOUT_US) ){ RMDBGLOG((ENABLE,"Sync Timeout!\n")); return RM_TIMEOUT; } } /* Wait for this value to change for the second time*/ while ( ((third = gbus_read_uint32(pgbus, (RMuint32)&context->fifo->xtaskToCPUSignal)) == second) || (third>255)) { RMDBGLOG((LOCALDBG,"Waiting on third == 0x%lx\n",third)); if( timer_interval_complete(pgbus, startTime, SYNC_TIMEOUT_US) ){ RMDBGLOG((ENABLE,"Sync Timeout!\n")); return RM_TIMEOUT; } } RMDBGLOG((ENABLE,"Rcvd signal from xtask.\n")); /* Signal acknowledgement to the xtask */ gbus_write_uint32(pgbus, (RMuint32)&context->fifo->cpuToXtaskSignal, 0); RMDBGLOG((ENABLE,"Sent signal to xtask\n")); return RM_OK;}/**************************************************************** Method Name ** xtask_rpc_init ** ** Description: ** Initialize the xtas_api context. This includes ** opening the gbus/llad, initializing the base * * address for communication with the xtask. ** ****************************************************************/RMstatus xtask_rpc_init( struct XtaskAPI* context, RMascii device[MAX_DEVICE_STRING], RMuint32 xrpc_base_addr, RMuint32 xrpc_size ){ /* Local Temp variables */ struct llad *pllad = 0; struct gbus *pgbus = 0; struct xrpc_block_header *pB; RMDBGLOG((ENABLE,"Open the llad with string \'%s\', xrpc_base_addr = 0x%08lx\n",device, xrpc_base_addr)); if( !xrpc_base_addr ) { RMDBGLOG((ENABLE,"xrpc_base_address is NULL ! \n")); return RM_ERROR; } if( xrpc_size < sizeof(struct xrpc_block_header) ) { RMDBGLOG((ENABLE,"memory allocated is too small. \n")); return RM_ERROR; } /* Open the llad */ pllad = llad_open(device); if (pllad == NULL) { RMDBGLOG((ENABLE, "unable to access device\n")); return RM_ERROR; } /* Open the gbus */ pgbus = gbus_open(pllad); if( pgbus == 0 ) { RMDBGLOG((ENABLE,"Failed to initialize the GBUS context\n")); return RM_ERROR; } /* Make sure that xrpc header is on 32-byte aligment for Cache boundary issue in XOS !!! */ if( xrpc_base_addr % 16 != 0 ) { RMDBGLOG((ENABLE, "xrpc_base_addr(0x%08lx) is not on a 16 byte cache boundary!\n",xrpc_base_addr )); return RM_ERROR; } pB = (struct xrpc_block_header *)xrpc_base_addr; /* update the xtaskContext */ context->pgbus = pgbus; context->pllad = pllad; context->pB = pB; context->base_addr = xrpc_base_addr; context->size = xrpc_size; /* By default events are enabled (backwards compatability) */ context->events_enabled = TRUE; return RM_OK;}/**************************************************************** Method Name ** xtask_rpc_close ** ** Description: ** Cleanup, reclaim memory occupied by the llad/gbus. ** ****************************************************************/void xtask_rpc_close( struct XtaskAPI *context ){ RMDBGLOG((LOCALDBG,"Closing Xtask API ref!\n")); /* Close the gbus and the llad */ if( context->pgbus ) gbus_close(context->pgbus); if( context->pllad ) llad_close(context->pllad); }/**************************************************************** Method Name ** xtask_semaphore_lock ** ** Description: ** Attempt to grab the semaphore, busy wait until it is ** available. **Not atomic ** ** ****************************************************************/RMstatus xtask_semaphore_lock( struct XtaskAPI* context /*, int timeout_ms */ ){ struct gbus *pgbus = context->pgbus; //RMDBGLOG((ENABLE,":::::::: Xtask_Semaphore_Lock() ...")); /* Busy wait for semahpore - maybe perform yeild here instead.*/ while( gbus_read_uint32( pgbus, (RMuint32)&context->fifo->semaphore) != 0 ); /* Acquire the semaphore */ gbus_write_uint32( pgbus, (RMuint32)&context->fifo->semaphore, 1 ); //RMDBGPRINT((ENABLE," locked!\n")); return RM_OK;}/**************************************************************** Method Name ** xtask_sempahore_release ** ** Description: ** Release the semaphore. ** ** ****************************************************************/RMstatus xtask_semaphore_release( struct XtaskAPI* context ){ struct gbus *pgbus = context->pgbus; gbus_write_uint32( pgbus, (RMuint32)&context->fifo->semaphore, 0 ); //RMDBGLOG((ENABLE,":::::::: Xtask_Semaphore_Released()!\n")); return RM_OK; }/**************************************************************** Method Name ** xtasl_rpc_enable_event_mode ** ** Description: ** Enable/Disable event mode. ** ** ****************************************************************/void xtask_rpc_enable_event_mode( struct XtaskAPI* context, RMbool enable){ context->events_enabled = enable;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?