apps: load_fw: use noblock mode remoteproc load function

Add demo to show how to use remoteproc no-blocking load function
to load executable.

Signed-off-by: Wendy Liang <jliang@xilinx.com>
This commit is contained in:
Wendy Liang
2018-07-18 16:37:55 -07:00
committed by wjliang
parent e9a11f1c57
commit 3325c6b729

View File

@@ -4,33 +4,10 @@
* Copyright(c) 2018 Xilinx Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Texas Instruments nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <metal/io.h>
#include <metal/sys.h>
#include <openamp/remoteproc.h>
#include <openamp/remoteproc_loader.h>
@@ -72,7 +49,8 @@ static XStatus IpiConfigure(XIpiPsu *const IpiInstPtr)
}
/* Init with the Cfg Data */
Status = XIpiPsu_CfgInitialize(IpiInstPtr, IpiCfgPtr, IpiCfgPtr->BaseAddress);
Status = XIpiPsu_CfgInitialize(IpiInstPtr, IpiCfgPtr,
IpiCfgPtr->BaseAddress);
if (XST_SUCCESS != Status) {
LPERROR("%s ERROR #%d in configuring IPI\n", __func__, Status);
return Status;
@@ -106,6 +84,120 @@ static void app_log_handler(enum metal_log_level level,
xil_printf("%s%s", level_strs[level], msg);
}
int load_exectuable_block(struct remoteproc *rproc,
struct image_store_ops *store_ops, void *store,
const char *img_path)
{
int ret;
(void)img_path;
if (rproc == NULL)
return -EINVAL;
/* Configure remoteproc to get ready to load executable */
remoteproc_config(rproc, NULL);
/* Load remoteproc executable */
LPRINTF("Start to load executable with remoteproc_load() \r\n");
ret = remoteproc_load(rproc, NULL, store, store_ops, NULL);
if (ret) {
LPRINTF("failed to load firmware\r\n");
return ret;
}
/* Start the processor */
ret = remoteproc_start(rproc);
if (ret) {
LPRINTF("failed to start processor\r\n");
return ret;
}
LPRINTF("successfully started the processor\r\n");
/* ... */
asm volatile("wfi");
LPRINTF("going to stop the processor\r\n");
remoteproc_stop(rproc);
/* application may want to do some cleanup before shutdown */
LPRINTF("going to shutdown the processor\r\n");
remoteproc_shutdown(rproc);
return 0;
}
int load_exectuable_noblock(struct remoteproc *rproc,
struct image_store_ops *store_ops, void *store,
const char *img_path)
{
int ret;
const void *img_data;
void *img_info = NULL;
metal_phys_addr_t pa;
struct metal_io_region *io;
size_t offset, noffset;
size_t len, nlen, nmlen;
unsigned char padding;
if (rproc == NULL)
return -EINVAL;
/* Configure remoteproc to get ready to load executable */
remoteproc_config(rproc, NULL);
/* Load remoteproc executable */
LPRINTF("Start to load executable with remoteproc_load() \r\n");
ret = store_ops->open(store, img_path, &img_data);
if (ret <= 0)
return -EINVAL;
offset = 0;
len = (size_t)ret;
do {
nlen = 0;
pa = METAL_BAD_PHYS;
io = NULL;
nmlen = 0;
LPRINTF("%s, loading 0x%lx,0x%lx\r\n",
__func__, offset, len);
ret = remoteproc_load_noblock(rproc, img_data, offset, len,
&img_info, &pa, &io, &noffset,
&nlen, &nmlen, &padding);
if (ret) {
LPERROR("failed to load executable, 0x%lx,0x%lx\r\n",
offset, len);
return ret;
}
if (nlen == 0)
break;
offset = noffset;
len = nlen;
ret = store_ops->load(store, noffset, nlen, &img_data, pa,
io, 1);
if (ret != (int)nlen) {
LPERROR("failed to load data to memory, 0x%lx,0x%lx\r\n",
noffset, nlen);
return ret;
}
if (nmlen > nlen && io != NULL) {
/* pad the rest of the memory with 0 */
size_t tmpoffset;
tmpoffset = metal_io_phys_to_offset(io, pa + nlen);
metal_io_block_set(io, tmpoffset, padding,
(nmlen - nlen));
}
} while(1);
/* Start the processor */
ret = remoteproc_start(rproc);
if (ret) {
LPRINTF("failed to start processor\r\n");
return ret;
}
LPRINTF("successfully started the processor\r\n");
/* ... */
asm volatile("wfi");
LPRINTF("going to stop the processor\r\n");
remoteproc_stop(rproc);
/* application may want to do some cleanup before shutdown */
LPRINTF("going to shutdown the processor\r\n");
remoteproc_shutdown(rproc);
return 0;
}
int main(void)
{
struct remoteproc rproc;
@@ -119,45 +211,40 @@ int main(void)
};
if (XST_SUCCESS != IpiConfigure(&IpiInst)) {
LPERROR("Failed to config IPI instance\n\r");
LPERROR("Failed to config IPI instance\r\n");
return -1;
}
if (XST_SUCCESS != XPm_InitXilpm(&IpiInst)) {
LPERROR("Failed to initialize PM\n\r");
LPERROR("Failed to initialize PM\r\n");
return -1;
}
LPRINTF("rproc app\n");
LPRINTF("Loading Exectuable Demo\n");
/* Initialize libmetal evironment */
metal_init(&metal_param);
/* Initialize remoteproc instance */
ret_rproc = remoteproc_init(&rproc, &r5_rproc_ops, &cpu_id);
if (!ret_rproc) {
LPRINTF("failed to initialize coprocessor\n\r");
LPRINTF("failed to initialize coprocessor\r\n");
return -1;
}
/* Load remtoeproc firmware */
LPRINTF("Start to load firmwaer\n\r");
ret = remoteproc_load(&rproc, NULL, store, &mem_image_store_ops, NULL);
if (ret) {
LPRINTF("failed to load firmware\n\r");
ret = load_exectuable_block(&rproc, &mem_image_store_ops, store, NULL);
if (ret < 0) {
LPERROR("load_exectuable_block failed\r\n");
/* Make sure the remote is shut down */
remoteproc_shutdown(&rproc);
return -1;
}
/* Start the processor */
ret = remoteproc_start(&rproc);
if (ret) {
LPRINTF("failed to start processor\n\r");
ret = load_exectuable_noblock(&rproc, &mem_image_store_ops, store,
NULL);
if (ret < 0) {
LPERROR("load_exectuable_noblock failed\r\n");
/* Make sure the remote is shut down */
remoteproc_shutdown(&rproc);
return -1;
}
LPRINTF("successfully started the processor\n\r");
/* ... */
asm volatile("wfi");
LPRINTF("going to stop the processor\n\r");
remoteproc_stop(&rproc);
/* application may want to do some cleanup before shutdown */
LPRINTF("going to shutdown the processor\n\r");
remoteproc_shutdown(&rproc);
remoteproc_remove(&rproc);
return 0;
return ret;
}