mirror of
https://github.com/OpenAMP/open-amp.git
synced 2026-02-05 18:51:28 +08:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user