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);
}
Ejemplo n.º 2
0
/*
 *  ======== 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;
}
Ejemplo n.º 3
0
/*
 * ======== 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;
}