static void bridge_load_firmware(void) { struct PROCESS_CONTEXT pr_ctxt; DSP_STATUS status; const char *argv[2]; argv[0] = firmware_file; argv[1] = NULL; pr_ctxt.hProcessor = NULL; status = PROC_Attach(0, NULL, &pr_ctxt.hProcessor, &pr_ctxt); if (DSP_FAILED(status)) goto func_err; status = PROC_Stop(pr_ctxt.hProcessor); if (DSP_FAILED(status)) goto func_err; status = PROC_Load(pr_ctxt.hProcessor, 1, argv, NULL); if (DSP_FAILED(status)) goto func_err; status = PROC_Start(pr_ctxt.hProcessor); if (DSP_FAILED(status)) goto func_err; status = PROC_Detach(&pr_ctxt); if (DSP_SUCCEEDED(status)) { pr_info("DSP recovery succeeded\n"); return; } func_err: pr_err("DSP could not be restarted, status = %x\n", status); }
/* * ======== procCreate ======== */ static Bool procCreate(Processor_Handle proc) { DSP_STATUS status = DSP_SOK; ZcpyMqtAttrs mqtAttrs; Bool retVal; GT_1trace(curTrace, GT_ENTER, "Processor_create_d> Enter(proc=0x%x)\n", proc); /* TODO:L ignoring cpuId string, using 0 for cpuId */ proc->cpuId = 0; /* call power on function -- either the real one, or the empty * stub defined by Global.xdt if power is not used. */ if (Power_on(&proc->powerHandle) == Power_EFAIL) { retVal = FALSE; GT_0trace(curTrace, GT_6CLASS, "Processor_create_d> Power_on failed.\n"); goto procCreate_return; } /* if using LAD: connect to LAD, startup DSP, attach with Link */ if (Global_useLinkArbiter) { /* connect to LAD */ ladStatus = LAD_connect(&handle); GT_2trace(curTrace, GT_2CLASS, "Processor_create_d> " "LAD_connect status = %x, handle = %x\n", ladStatus, handle); if (ladStatus != LAD_SUCCESS) { GT_1trace(curTrace, GT_7CLASS, "Processor_create_d> " "LAD_connect FAILED, status = [0x%x]\n", ladStatus); goto ladfail; } /* startup the DSP (if it isn't already started) */ GT_2trace(curTrace, GT_2CLASS, "Processor_create_d> " "Loading %s on DSP, linkConfigName= %s ...\n", proc->imageName, proc->linkConfigName); ladStatus = LAD_startupDsp(handle, proc->cpuId, proc->linkConfigName, proc->imageName); GT_1trace(curTrace, GT_2CLASS, "Processor_create_d> " "LAD_startupDsp status = %x\n", ladStatus); /* on success, continue */ if ((ladStatus == LAD_SUCCESS) || (ladStatus == LAD_ALREADYRUNNING)) { #ifndef WIN32 /* * Must still call PROC_Attach from this app's process. (For * WinCE, LAD runs in the same process, so PROC_Attach() returns * an error.) */ status = PROC_Attach(proc->cpuId, NULL); if (!DSP_SUCCEEDED(status)) { GT_1trace(curTrace, GT_7CLASS, "Processor_create_d> " "PROC_Attach following LAD_startupDsp FAILED, " "status=[0x%x]\n", (Uns) status); goto ladfail; } /* must still call POOL_Open from this app (NULL attributes) */ status = POOL_Open (Global_cePoolId, NULL) ; if (!DSP_SUCCEEDED(status)) { GT_1trace(curTrace, GT_7CLASS, "Processor_create_d> " "POOL_Open following LAD_startupDsp FAILED, " "status=[0x%x]\n", (Uns) status); } #endif } /* else, on fail, abort */ else { GT_1trace(curTrace, GT_7CLASS, "Processor_create_d> " "LAD_startupDsp FAILED, status = [0x%x]\n", ladStatus); goto ladfail; } } /* end of 'if using LAD' */ /* else, if no LAD, call Link's startup APIs directly */ else { /* * Create and initialize the PROC object. */ GT_0trace(curTrace, GT_2CLASS, "Processor_create_d> " "Initializing DSP PROC...\n"); modifyDefaultLinkCfgObjectForCENeeds(); modifyDefaultLinkCfgObjectBasedOnUserCfgData(proc->imageName); dumpLinkCfgObj(&ti_sdo_ce_ipc_Processor_linkcfg); status = PROC_setup( &ti_sdo_ce_ipc_Processor_linkcfg ); if (!DSP_SUCCEEDED(status)) { goto fail; } /* * Attach the Dsp. */ GT_0trace(curTrace, GT_2CLASS, "Processor_create_d> " "Attaching to DSP PROC...\n"); status = PROC_Attach(proc->cpuId, NULL); if (!DSP_SUCCEEDED(status)) { goto fail; } /* * Open a pool with buffers for both the control messages use by the * transport and the application. */ GT_0trace(curTrace, GT_2CLASS, "Processor_create_d> " "Opening MSGQ pool...\n"); status = POOL_Open(Global_cePoolId, &Global_cePoolAttrs); if (!DSP_SUCCEEDED(status)) { goto fail; } /* * Load the executable on the DSP. */ GT_2trace(curTrace, GT_2CLASS, "Processor_create_d> " "Loading %s on DSP (%d args)...\n", proc->imageName, proc->attrs.argc); status = PROC_Load(proc->cpuId, proc->imageName, proc->attrs.argc, proc->attrs.argv); if (!DSP_SUCCEEDED(status)) { goto fail; } /* * Start execution on DSP. */ GT_0trace(curTrace, GT_2CLASS, "Processor_create_d> " "Starting DSP PROC...\n"); status = PROC_Start(proc->cpuId); if (!DSP_SUCCEEDED(status)) { goto fail; } /* * Open the remote transport to the DSP. */ GT_0trace(curTrace, GT_2CLASS, "Processor_create_d> " "Opening remote transport...\n"); /* tell the transport which open pool id to use for ctrl messages */ mqtAttrs.poolId = Global_cePoolId; status = MSGQ_TransportOpen(proc->cpuId, &mqtAttrs); if (!DSP_SUCCEEDED(status)) { goto fail; } } /* end of else to using LAD */ /* * Connect to the Power on the DSP */ if (Power_connect(proc->powerHandle) == Power_EFAIL) { goto fail; } proc->connected = TRUE; if (Global_getenv("CE_DSPDEBUG") != NULL) { printf("Codec Engine system message (b/c CE_DSPDEBUG=1) : DSP image " "loaded and started, press Enter to continue: "); getchar(); } retVal = TRUE; goto procCreate_return; /* TODO:[4] should try those asyncErrorHandlers that link supports? * (MSGQ_SetErrorHandler) */ fail: GT_4trace(curTrace, GT_7CLASS, "Processor_create_d> " "Loading and starting DSP server '%s' FAILED, status=[0x%x] " "(look for error code 'DSP_EBASE + 0x%x' in " "dsplink*/packages/dsplink/gpp/inc/usr/errbase.h) %s\n", proc->imageName, status, status & 0x7fff, status == DSP_ERANGE ? "This error code typically indicates a problem with the DSP memory " "map, i.e. it is different from what the Arm side specified; check " "the DSP server's memory map in your Arm application .cfg script, " "and make sure you have set 'armDspLinkConfig' " "configuration variable correctly (for details, refer to the " "documentation for ti.sdo.ce.Engine.xdc). Also, verify that " "the DSPLINKMEM segment on the DSP is large enough. " : "" ); ladfail: procDelete(proc); retVal = FALSE; procCreate_return: GT_1trace(curTrace, GT_2CLASS, "Processor_create_d> return (%d)\n", retVal); return retVal; }
/* * ======== PROCWRAP_Load ======== */ u32 PROCWRAP_Load(union Trapped_Args *args, void *pr_ctxt) { s32 i, len; DSP_STATUS status = DSP_SOK; char *temp; s32 count = args->ARGS_PROC_LOAD.iArgc; u8 **argv, **envp = NULL; DBC_Require(count > 0); DBC_Require(count <= MAX_LOADARGS); argv = MEM_Alloc(count * sizeof(u8 *), MEM_NONPAGED); if (!argv) { status = DSP_EMEMORY; goto func_cont; } cp_fm_usr(argv, args->ARGS_PROC_LOAD.aArgv, status, count); if (DSP_FAILED(status)) { MEM_Free(argv); argv = NULL; goto func_cont; } for (i = 0; i < count; i++) { if (argv[i]) { /* User space pointer to argument */ temp = (char *) argv[i]; /* len is increased by 1 to accommodate NULL */ len = strlen_user((char *)temp) + 1; /* Kernel space pointer to argument */ argv[i] = MEM_Alloc(len, MEM_NONPAGED); if (argv[i]) { cp_fm_usr(argv[i], temp, status, len); if (DSP_FAILED(status)) { MEM_Free(argv[i]); argv[i] = NULL; goto func_cont; } } else { status = DSP_EMEMORY; goto func_cont; } } } /* TODO: validate this */ if (args->ARGS_PROC_LOAD.aEnvp) { /* number of elements in the envp array including NULL */ count = 0; do { get_user(temp, args->ARGS_PROC_LOAD.aEnvp + count); count++; } while (temp); envp = MEM_Alloc(count * sizeof(u8 *), MEM_NONPAGED); if (!envp) { status = DSP_EMEMORY; goto func_cont; } cp_fm_usr(envp, args->ARGS_PROC_LOAD.aEnvp, status, count); if (DSP_FAILED(status)) { MEM_Free(envp); envp = NULL; goto func_cont; } for (i = 0; envp[i]; i++) { /* User space pointer to argument */ temp = (char *)envp[i]; /* len is increased by 1 to accommodate NULL */ len = strlen_user((char *)temp) + 1; /* Kernel space pointer to argument */ envp[i] = MEM_Alloc(len, MEM_NONPAGED); if (envp[i]) { cp_fm_usr(envp[i], temp, status, len); if (DSP_FAILED(status)) { MEM_Free(envp[i]); envp[i] = NULL; goto func_cont; } } else { status = DSP_EMEMORY; goto func_cont; } } } GT_5trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Load, hProcessor: 0x%x\n\tiArgc:" "0x%x\n\taArgv: 0x%x\n\taArgv[0]: %s\n\taEnvp: 0x%0x\n", args->ARGS_PROC_LOAD.hProcessor, args->ARGS_PROC_LOAD.iArgc, args->ARGS_PROC_LOAD.aArgv, argv[0], args->ARGS_PROC_LOAD.aEnvp); if (DSP_SUCCEEDED(status)) { status = PROC_Load(args->ARGS_PROC_LOAD.hProcessor, args->ARGS_PROC_LOAD.iArgc, (CONST char **)argv, (CONST char **)envp); } func_cont: if (envp) { i = 0; while (envp[i]) MEM_Free(envp[i++]); MEM_Free(envp); } if (argv) { count = args->ARGS_PROC_LOAD.iArgc; for (i = 0; (i < count) && argv[i]; i++) MEM_Free(argv[i]); MEM_Free(argv); } return status; }