📄 xtask_rpc.c
字号:
/***************************************************************************** Copyright (c) Sigma Designs, Inc. 2005. All rights reserved.*//*** @file xtask_rpc.c** @brief RPC interface between CPU/Xtask.* ** @author Alan Liddeke* ****************************************************************************//*--------------------------------------------------------------------------- INCLUDES ---------------------------------------------------------------------------*/#ifdef USE_WIN_CE#include "wince_gbus.h"#else#include "llad/include/gbus.h"#endif#include "emhwlib/include/emhwlib_event.h"#include "xos/include/xos_xrpc.h"#include "xtask_rpc.h"#include "delay.h"#ifdef USE_WAIT_FOR_VSYNC#include "vsync.h"#endif/*--------------------------------------------------------------------------- CONSTANT LITERALS ---------------------------------------------------------------------------*/#if 0#define LOCALDBG ENABLE#else#define LOCALDBG DISABLE#endif#if 0#define VERBOSE_DEBUG#endif#define XTASK_EVENT_KILL 0xFFFFFFFF#define HW_TIMER_ADDR REG_BASE_system_block+SYS_xtal_in_cnt#define US_PER_S (1000000)#define SYNC_TIMEOUT_US (10*US_PER_S) // 10 Second timeout for sync#define TICKS_PER_US (27)#define MAX_TIMEOUT ((0xFFFFFFFF / TICKS_PER_US)/2)#define CPU_LOCALRAM_STAGE (REG_BASE_cpu_block+CPU_LOCALRAM_SIZE-4)/*--------------------------------------------------------------------------- FUNCTIONS ---------------------------------------------------------------------------*//* Get an initial value for use of the HW 27MHZ counter register * This counter is a 32-bit register and thus overflows ((2^32) - 1) / 27 Mhz * => 159 seconds. This requires that the interval for which the timer will * be used is less than or equal to 159 seconds. This timer is only available * on TANGO2 (TODO: add for TANGO3) */static RMuint32 timer_start(struct gbus* pgbus){#if (EM86XX_CHIP == EM86XX_CHIPID_TANGO2) return gbus_read_uint32(pgbus,HW_TIMER_ADDR);#else return 0;#endif}static RMbool timer_interval_complete(struct gbus* pgbus, RMuint32 startTime, RMuint32 timeInterval_us){#if (EM86XX_CHIP == EM86XX_CHIPID_TANGO2) RMuint32 currentTime = gbus_read_uint32(pgbus,HW_TIMER_ADDR); RMuint32 ticksElapsed; if( timeInterval_us > (0xFFFFFFFF / TICKS_PER_US) ) RMDBGLOG((ENABLE,"ERROR: Timer Interval can never be reached !\n")); if( currentTime < startTime ) { /* Handle overflow condition */ ticksElapsed = (currentTime) + (0xFFFFFFFF - startTime) + 1; } else { ticksElapsed = currentTime - startTime; } if( ((ticksElapsed)/(TICKS_PER_US)) >= timeInterval_us ) return TRUE; else return FALSE;#else /* Always return true, no timer present */ return TRUE;#endif}/**************************************************************** Method Name ** xtask_rpc_start ** ** Description: ** Call -xstart on the given xtask image. ** ** ****************************************************************/RMstatus xtask_rpc_start( struct XtaskAPI* context,struct XstartParams* params ){ struct xrpc_block_header *pB = context->pB; struct gbus *pgbus = context->pgbus; RMuint32 base_addr = context->base_addr; RMuint32 image = context->image; int xPid; RMDBGLOG((LOCALDBG,"Starting Xtask.\n")); /* Start the xtask on the selected image */ gbus_write_uint32(pgbus, (RMuint32)&pB->xrpcid,XRPC_ID_XSTART); gbus_write_uint32(pgbus, (RMuint32)&pB->param0, image); /* If no params are specified (NULL) then all are set to '0' and * the communication area is set to the top half of the debug fifo.*/ if( params != NULL ) { /* The following get passed into Xtask_entry(a0,a1,a2,a3) in order * a0 = ruaCommAddr, * a1 = flashPageNum * a2 = User defined. * a3 = User defined. * */ gbus_write_uint32(pgbus, (RMuint32)&pB->param1, params->ruaCommAddr); gbus_write_uint32(pgbus, (RMuint32)&pB->param2, params->flashPageNum); gbus_write_uint32(pgbus, (RMuint32)&pB->param3, params->a2); gbus_write_uint32(pgbus, (RMuint32)&pB->param4, params->a3); } else { gbus_write_uint32(pgbus, (RMuint32)&pB->param1, 0); gbus_write_uint32(pgbus, (RMuint32)&pB->param2, 0); gbus_write_uint32(pgbus, (RMuint32)&pB->param3, 0); gbus_write_uint32(pgbus, (RMuint32)&pB->param4, 0); } /* This is mandatory: */ gbus_write_uint32(pgbus, (RMuint32)&pB->headerandblocksize, sizeof(struct xrpc_block_header));#ifdef USE_WAIT_FOR_VSYNC wait_for_vsync(pgbus);#endif if (doxrpc(pgbus,base_addr) != RM_OK) { RMDBGLOG((ENABLE,"xrpc failed\n")); RMDBGLOG((ENABLE,": pgbus=%lld\n" ": image=%d\n", pgbus,image)); return RM_ERROR; } /* Determine the PID of the new xtask */ xPid = gbus_read_uint32(pgbus,(RMuint32)&pB->param0); context->xPid = xPid; if( params ) { context->fifo = (struct XtaskFIFO*)(params->ruaCommAddr); } else { // By default use the top half of the Debug fifo for rpc communication context->fifo = (struct XtaskFIFO*)rpc2xtask_fifo_base_addr[xPid]; } /* Semaphore must be initialized before making any calls. */ xtask_semaphore_release(context); // Set to zero! /* Zero the procedure register to prevent unwanted call to the xtask at startup */ gbus_write_uint32( pgbus,(RMuint32)&(context->fifo->procedureFd), 0x00000000); if( xPid == -1 ) { RMDBGLOG((ENABLE, "Unable to launch Xtask, too many running.\n")); return RM_ERROR; } else { RMDBGLOG((LOCALDBG,"Xtask Started.\n")); return RM_OK; }}/**************************************************************** Method Name ** xtask_rpc_preloadxtask ** ** Description: ** Indicate that the xtask was preloaded ** Returns RM_OK for success, RM_ERROR for failure. ** ****************************************************************/RMstatus xtask_rpc_preloadxtask( struct XtaskAPI* context, RMuint32 slot){ /* Copy back the image number the xtask was loaded to */ context->image = slot; return RM_OK; }/**************************************************************** Method Name ** xtask_rpc_loadxtask ** ** Description: ** Load the given XLOAD binary ** Returns RM_OK for success, RM_ERROR for failure. ** ****************************************************************/RMstatus xtask_rpc_loadxtask( struct XtaskAPI* context, RMuint8* pXload, RMuint32 xloadSize){ struct xrpc_block_header *pB = context->pB; struct gbus *pgbus = context->pgbus; RMuint32 base_addr = context->base_addr; RMuint32 size = xloadSize; /* Make sure that the binary will fit within the buffer */ if( context->size < sizeof(struct xrpc_block_header) + xloadSize ) { RMDBGLOG((ENABLE,"xtask_rpc_loadxtask: ERROR ! xrpc memory area not large enough to load xtask!\n")); return RM_ERROR; } /** Sanity Checks **/ /* Make sure that the chip is of valid type */ if ((gbus_read_uint16(pgbus, REG_BASE_host_interface + PCI_REG0) & ~0xf) != 0x8630) { RMDBGLOG((ENABLE, "for tango2 only.\n")); return RM_ERROR; } /* Make sure that local RAM is available */ if (gbus_read_uint32(pgbus, REG_BASE_cpu_block + G2L_RESET_CONTROL) == 3) { RMDBGLOG((ENABLE, "cpu in reset 3, I can't access local ram\n")); return RM_ERROR; } /** Write out the Block Header and Data **/ /* Set the XRPC header */ gbus_write_uint32(pgbus,(RMuint32)&pB->callerid,XRPC_CALLERID_IGNORED); gbus_write_uint32(pgbus,(RMuint32)&pB->headerandblocksize,(sizeof(struct xrpc_block_header)+63)&~63); /* Write the binary xtask data to the XRPC data location */ RMDBGLOG((ENABLE,"Xtask Load size = %ld\n",xloadSize)); gbus_write_data8(pgbus, (RMuint32)(pB+1), pXload, xloadSize); gbus_write_uint32(pgbus,(RMuint32)&pB->xrpcid,XRPC_ID_XLOAD); /* ! Write out the size */ if ((gbus_read_uint32(pgbus,(RMuint32)(pB+1))>>24)==XLOAD_SEKID_CLEAR) gbus_write_uint32(pgbus,(RMuint32)&pB->param0,size-XLOAD_CLEAR_HEADERSIZE); else gbus_write_uint32(pgbus,(RMuint32)&pB->param0,size-XLOAD_CIPHERED_HEADERSIZE); // by putting garbage here, you can crash Maa. Fixed with Mac. gbus_write_uint32(pgbus,(RMuint32)&pB->param1,0); gbus_write_uint32(pgbus,(RMuint32)&pB->param2,0); gbus_write_uint32(pgbus,(RMuint32)&pB->param3,0); gbus_write_uint32(pgbus,(RMuint32)&pB->param4,0); gbus_write_uint32(pgbus,(RMuint32)&pB->headerandblocksize,sizeof(struct xrpc_block_header)+size); #ifdef VERBOSE_DEBUG //DEBUG: Print out header and XLOAD binary: { RMuint32 i; /* write the block header out */ RMDBGLOG((LOCALDBG," block header: ")); for(i=0; i< 8;i++ ) { RMDBGPRINT(( LOCALDBG, "0x%08lx, ", gbus_read_uint32( pgbus, ((RMuint32)(pB))+(RMuint32)(4*i) ) )); } /* Write the rest */ RMDBGPRINT((ENABLE,"\n\ngbus read of the XLOAD binary: \n")); for(i=0; i<xloadSize; i++) { if( i%32 == 0 && i != 0) { RMDBGPRINT((LOCALDBG,"\n")); } RMDBGPRINT(( LOCALDBG, "%02X", gbus_read_uint8(pgbus, (RMuint32)( ((RMuint32)pB) + sizeof(struct xrpc_block_header)+i)) )); } RMDBGPRINT((LOCALDBG,"\n\n\nActual xload binary: \n")); /* Write out the actual values */ for(i=0; i< xloadSize; i++) { if(i%32 == 0 && i != 0) { RMDBGPRINT((LOCALDBG,"\n")); } RMDBGPRINT((LOCALDBG, "%02X", ((RMuint8*)pXload)[i])); } RMDBGPRINT((ENABLE,"\n\n\n")); }#endif /** Perform XRPC **/ if ( doxrpc(pgbus,base_addr) == RM_OK ) { RMDBGLOG((LOCALDBG,"xrpc Load succeeded\n")); } else {#ifdef VERBOSE_DEBUG { RMuint32 i; /* write the block header out */ RMDBGLOG((LOCALDBG," block header: ")); for(i=0; i< 8;i++ ) { RMDBGPRINT(( LOCALDBG, "0x%08lx, ", gbus_read_uint32( pgbus, ((RMuint32)(pB))+(RMuint32)(4*i) ) )); } /* Write the rest */ RMDBGPRINT((ENABLE,"\n\ngbus read of the XLOAD binary: \n")); for(i=0; i<xloadSize; i++) { if( i%32 == 0 && i != 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -