mirror of
https://github.com/OpenAMP/open-amp.git
synced 2026-09-21 15:14:02 +08:00
examples: update Xilinx example code.
This provides bug fixes and enhancements to the Xilinx-specific example code, and a couple of small fixes to the linux example code. Signed-off-by: Ed Mooring <ed.mooring@linaro.org>
This commit is contained in:
committed by
Arnaud Pouliquen
parent
f98eb2a670
commit
007f2fe640
@@ -3,6 +3,7 @@ collector_create (APP_LIB_DIRS "")
|
||||
collector_create (APP_INC_DIRS "")
|
||||
collector_create (APP_LIB_DEPS "")
|
||||
|
||||
collector_create (APP_EXTRA_C_FLAGS "")
|
||||
set (APPS_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
set (APPS_SHARE_DIR "${CMAKE_CURRENT_BINARY_DIR}/share")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
set (_cflags "${CMAKE_C_FLAGS} ${APP_EXTRA_C_FLAGS}")
|
||||
collector_list (_app_extra_c_flags APP_EXTRA_C_FLAGS)
|
||||
set (_cflags "${CMAKE_C_FLAGS} ${_app_extra_c_flags}")
|
||||
set (_fw_dir "${APPS_SHARE_DIR}")
|
||||
|
||||
collector_list (_list PROJECT_INC_DIRS)
|
||||
@@ -11,21 +11,24 @@ collector_list (_app_list APP_LIB_DIRS)
|
||||
link_directories (${_list} ${_app_list})
|
||||
|
||||
get_property (_linker_opt GLOBAL PROPERTY APP_LINKER_OPT)
|
||||
collect (PROJECT_LIB_DEPS xilpm)
|
||||
collector_list (_deps PROJECT_LIB_DEPS)
|
||||
|
||||
set (OPENAMP_LIB open_amp)
|
||||
|
||||
foreach (_app load_fw)
|
||||
collector_list (_sources APP_COMMON_SOURCES)
|
||||
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/${_app}.c")
|
||||
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/mem_image_store.c")
|
||||
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/zynqmp_r5_lcm_rproc_example.c")
|
||||
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/zynqmp_apu_lcm_rproc_example.c")
|
||||
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/zynqmp_rpu_lcm_rproc_example.c")
|
||||
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/platform_info.c")
|
||||
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/${_app}.c")
|
||||
|
||||
if (WITH_STATIC_LIB)
|
||||
add_executable (${_app}.out ${_sources})
|
||||
set_source_files_properties(${_sources} PROPERTIES COMPILE_FLAGS "${_cflags}")
|
||||
|
||||
target_link_libraries(${_app}.out -Wl,-Map=${_app}.map -Wl,--gc-sections -T"${CMAKE_CURRENT_SOURCE_DIR}/lscript.ld" -Wl,--start-group ${OPENAMP_LIB}-static -lxilpm ${_deps} -Wl,--end-group)
|
||||
target_link_libraries(${_app}.out -Wl,-Map=${_app}.map -Wl,--gc-sections -T"${CMAKE_CURRENT_SOURCE_DIR}/lscript.ld" -Wl,--start-group ${OPENAMP_LIB}-static ${_deps} -Wl,--end-group)
|
||||
|
||||
install (TARGETS ${_app}.out RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif (WITH_STATIC_LIB)
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright(c) 2019 Xilinx Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
|
||||
#include <metal/alloc.h>
|
||||
#include <metal/io.h>
|
||||
#include <metal/sys.h>
|
||||
#include <metal/utilities.h>
|
||||
#include <openamp/remoteproc.h>
|
||||
#include <openamp/remoteproc_loader.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
/* Xilinx headers */
|
||||
#include <pm_api_sys.h>
|
||||
#include <xil_mpu.h>
|
||||
#include <xil_printf.h>
|
||||
#include <xreg_cortexr5.h>
|
||||
|
||||
#ifdef versal
|
||||
#include <xpm_nodeid.h>
|
||||
#include <xpm_defs.h>
|
||||
|
||||
#ifndef NODE_APU_0
|
||||
#define NODE_APU_0 PM_DEV_ACPU_0
|
||||
#endif
|
||||
#ifndef NODE_APU_1
|
||||
#define NODE_APU_1 PM_DEV_ACPU_1
|
||||
#endif
|
||||
#ifndef NODE_RPU_0
|
||||
#define NODE_RPU_0 PM_DEV_RPU0_0
|
||||
#endif
|
||||
#ifndef NODE_RPU
|
||||
#define NODE_RPU PM_DEV_RPU0_0
|
||||
#endif
|
||||
|
||||
#ifndef NODE_RPU_1
|
||||
#define NODE_RPU_1 PM_DEV_RPU0_1
|
||||
#endif
|
||||
|
||||
#ifndef NODE_TCM_0_A
|
||||
#define NODE_TCM_0_A PM_DEV_TCM_0_A
|
||||
#endif
|
||||
#ifndef NODE_TCM_0_B
|
||||
#define NODE_TCM_0_B PM_DEV_TCM_0_B
|
||||
#endif
|
||||
#ifndef NODE_TCM_1_A
|
||||
#define NODE_TCM_1_A PM_DEV_TCM_1_A
|
||||
#endif
|
||||
#ifndef NODE_TCM_1_B
|
||||
#define NODE_TCM_1_B PM_DEV_TCM_1_B
|
||||
#endif
|
||||
|
||||
#ifndef NODE_DDR
|
||||
#define NODE_DDR PM_DEV_DDR_0
|
||||
#endif
|
||||
|
||||
#ifndef NODE_OCM_BANK_0
|
||||
#define NODE_OCM_BANK_0 PM_DEV_OCM_0
|
||||
#endif
|
||||
#ifndef NODE_OCM_BANK_1
|
||||
#define NODE_OCM_BANK_1 PM_DEV_OCM_1
|
||||
#endif
|
||||
#ifndef NODE_OCM_BANK_2
|
||||
#define NODE_OCM_BANK_2 PM_DEV_OCM_2
|
||||
#endif
|
||||
#ifndef NODE_OCM_BANK_3
|
||||
#define NODE_OCM_BANK_3 PM_DEV_OCM_3
|
||||
#endif
|
||||
|
||||
/* Requirement limits */
|
||||
#define XPM_MAX_CAPABILITY (PM_CAP_ACCESS | PM_CAP_CONTEXT | PM_CAP_WAKEUP)
|
||||
#define XPM_MAX_LATENCY (0xFFFFU)
|
||||
#define XPM_MAX_QOS (100)
|
||||
#define XPM_MIN_CAPABILITY (0)
|
||||
#define XPM_MIN_LATENCY (0)
|
||||
#define XPM_MIN_QOS (0)
|
||||
#define XPM_DEF_CAPABILITY XPM_MAX_CAPABILITY
|
||||
#define XPM_DEF_LATENCY XPM_MAX_LATENCY
|
||||
#define XPM_DEF_QOS XPM_MAX_QOS
|
||||
|
||||
enum XPmRequestAck {
|
||||
REQUEST_ACK_NO = 1,
|
||||
REQUEST_ACK_BLOCKING,
|
||||
REQUEST_ACK_NON_BLOCKING,
|
||||
REQUEST_ACK_CB_CERROR,
|
||||
};
|
||||
|
||||
#else /* zynqmp */
|
||||
#include <pm_defs.h>
|
||||
#define XPM_MAX_QOS MAX_QOS
|
||||
#define XPM_MIN_QOS (0)
|
||||
#endif /* versal */
|
||||
|
||||
#define LPRINTF(format, ...) xil_printf(format, ##__VA_ARGS__)
|
||||
//#define LPRINTF(format, ...)
|
||||
#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
|
||||
|
||||
struct rproc_priv {
|
||||
struct remoteproc *rproc;
|
||||
int cpu_id;
|
||||
};
|
||||
|
||||
#endif /* COMMON_H_ */
|
||||
@@ -7,22 +7,9 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <metal/io.h>
|
||||
#include <metal/sys.h>
|
||||
#include <openamp/remoteproc.h>
|
||||
#include <openamp/remoteproc_loader.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
/* Xilinx headers */
|
||||
#include <pm_api_sys.h>
|
||||
#include <pm_defs.h>
|
||||
#include <xil_printf.h>
|
||||
#include <platform_info.h>
|
||||
#include <common.h>
|
||||
|
||||
#define LPRINTF(format, ...) xil_printf(format, ##__VA_ARGS__)
|
||||
//#define LPRINTF(format, ...)
|
||||
#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
|
||||
|
||||
extern struct remoteproc_ops r5_rproc_ops;
|
||||
extern struct image_store_ops mem_image_store_ops;
|
||||
|
||||
struct mem_file {
|
||||
@@ -33,57 +20,6 @@ static struct mem_file image = {
|
||||
.base = (void *)0x3ED00000,
|
||||
};
|
||||
|
||||
static XIpiPsu IpiInst;
|
||||
|
||||
static XStatus IpiConfigure(XIpiPsu *const IpiInstPtr)
|
||||
{
|
||||
XStatus Status;
|
||||
XIpiPsu_Config *IpiCfgPtr;
|
||||
|
||||
/* Look Up the config data */
|
||||
IpiCfgPtr = XIpiPsu_LookupConfig(XPAR_XIPIPSU_0_DEVICE_ID);
|
||||
if (NULL == IpiCfgPtr) {
|
||||
Status = XST_FAILURE;
|
||||
LPERROR("%s ERROR in getting CfgPtr\r\n", __func__);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Init with the Cfg Data */
|
||||
Status = XIpiPsu_CfgInitialize(IpiInstPtr, IpiCfgPtr,
|
||||
IpiCfgPtr->BaseAddress);
|
||||
if (XST_SUCCESS != Status) {
|
||||
LPERROR("%s ERROR #%d in configuring IPI\r\n", __func__, Status);
|
||||
return Status;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
static void app_log_handler(enum metal_log_level level,
|
||||
const char *format, ...)
|
||||
{
|
||||
char msg[1024];
|
||||
va_list args;
|
||||
static const char *level_strs[] = {
|
||||
"metal: emergency: ",
|
||||
"metal: alert: ",
|
||||
"metal: critical: ",
|
||||
"metal: error: ",
|
||||
"metal: warning: ",
|
||||
"metal: notice: ",
|
||||
"metal: info: ",
|
||||
"metal: debug: ",
|
||||
};
|
||||
|
||||
va_start(args, format);
|
||||
vsnprintf(msg, sizeof(msg), format, args);
|
||||
va_end(args);
|
||||
|
||||
if (level <= METAL_LOG_EMERGENCY || level > METAL_LOG_DEBUG)
|
||||
level = METAL_LOG_EMERGENCY;
|
||||
|
||||
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)
|
||||
@@ -95,6 +31,7 @@ int load_exectuable_block(struct remoteproc *rproc,
|
||||
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);
|
||||
@@ -109,6 +46,7 @@ int load_exectuable_block(struct remoteproc *rproc,
|
||||
return ret;
|
||||
}
|
||||
LPRINTF("successfully started the processor\r\n");
|
||||
#ifndef RPU_BOOT_LINUX
|
||||
/* ... */
|
||||
asm volatile("wfi");
|
||||
LPRINTF("going to stop the processor\r\n");
|
||||
@@ -116,9 +54,11 @@ int load_exectuable_block(struct remoteproc *rproc,
|
||||
/* application may want to do some cleanup before shutdown */
|
||||
LPRINTF("going to shutdown the processor\r\n");
|
||||
remoteproc_shutdown(rproc);
|
||||
#endif /* RPU_BOOT_LINUX */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef RPU_BOOT_LINUX
|
||||
int load_exectuable_noblock(struct remoteproc *rproc,
|
||||
struct image_store_ops *store_ops, void *store,
|
||||
const char *img_path)
|
||||
@@ -196,55 +136,38 @@ int load_exectuable_noblock(struct remoteproc *rproc,
|
||||
remoteproc_shutdown(rproc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* RPU_BOOT_LINUX */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct remoteproc rproc;
|
||||
struct remoteproc *ret_rproc;
|
||||
struct remoteproc *rproc = NULL;
|
||||
void *store = ℑ
|
||||
unsigned int cpu_id = NODE_RPU_1;
|
||||
unsigned int cpu_id = LOAD_FW_TARGET;
|
||||
int ret;
|
||||
struct metal_init_params metal_param = {
|
||||
.log_handler = app_log_handler,
|
||||
.log_level = METAL_LOG_DEBUG,
|
||||
};
|
||||
|
||||
if (XST_SUCCESS != IpiConfigure(&IpiInst)) {
|
||||
LPERROR("Failed to config IPI instance\r\n");
|
||||
LPRINTF("Loading Exectuable Demo\n");
|
||||
rproc = app_init(cpu_id);
|
||||
if (!rproc) {
|
||||
LPERROR("app_init failed\r\n");
|
||||
return -1;
|
||||
}
|
||||
if (XST_SUCCESS != XPm_InitXilpm(&IpiInst)) {
|
||||
LPERROR("Failed to initialize PM\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LPRINTF("Loading Exectuable Demo\r\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\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = load_exectuable_block(&rproc, &mem_image_store_ops, store, NULL);
|
||||
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);
|
||||
remoteproc_shutdown(rproc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = load_exectuable_noblock(&rproc, &mem_image_store_ops, store,
|
||||
#ifndef RPU_BOOT_LINUX
|
||||
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);
|
||||
remoteproc_shutdown(rproc);
|
||||
return -1;
|
||||
}
|
||||
remoteproc_remove(&rproc);
|
||||
#endif /* RPU_BOOT_LINUX */
|
||||
remoteproc_remove(rproc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -7,19 +7,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <metal/io.h>
|
||||
#include <metal/sys.h>
|
||||
#include <openamp/remoteproc_loader.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
/* Xilinx headers */
|
||||
#include <pm_api_sys.h>
|
||||
#include <pm_defs.h>
|
||||
#include <xil_printf.h>
|
||||
|
||||
#define LPRINTF(format, ...) xil_printf(format, ##__VA_ARGS__)
|
||||
//#define LPRINTF(format, ...)
|
||||
#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
|
||||
#include <common.h>
|
||||
|
||||
struct mem_file {
|
||||
const void *base;
|
||||
@@ -56,7 +44,7 @@ int mem_image_load(void *store, size_t offset, size_t size,
|
||||
|
||||
(void)is_blocking;
|
||||
|
||||
LPRINTF("%s: offset=0x%x, size=0x%x\r\n",
|
||||
LPRINTF("%s: offset=0x%x, size=0x%x\n\r",
|
||||
__func__, offset, size);
|
||||
if (pa == METAL_BAD_PHYS) {
|
||||
if (data == NULL) {
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright(c) 2019 Xilinx Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <platform_info.h>
|
||||
#include <common.h>
|
||||
|
||||
extern struct remoteproc_ops zynqmp_apu_rproc_ops;
|
||||
extern struct remoteproc_ops zynqmp_rpu_rproc_ops;
|
||||
|
||||
static struct remoteproc rproc_inst;
|
||||
static struct remoteproc_ops ops;
|
||||
|
||||
static struct remoteproc * platform_create_proc(unsigned int cpu_id)
|
||||
{
|
||||
struct remoteproc * rproc;
|
||||
if (NODE_RPU_0 <= LOAD_FW_TARGET && LOAD_FW_TARGET <= NODE_RPU_1)
|
||||
ops = zynqmp_rpu_rproc_ops;
|
||||
else if (NODE_APU_0 <= LOAD_FW_TARGET && LOAD_FW_TARGET <= NODE_APU_1)
|
||||
ops = zynqmp_apu_rproc_ops;
|
||||
else
|
||||
return NULL;
|
||||
|
||||
rproc = remoteproc_init(&rproc_inst, &ops, &cpu_id);
|
||||
if (!rproc)
|
||||
return NULL;
|
||||
return &rproc_inst;
|
||||
}
|
||||
|
||||
static void app_log_handler(enum metal_log_level level,
|
||||
const char *format, ...)
|
||||
{
|
||||
char msg[1024];
|
||||
va_list args;
|
||||
static const char *level_strs[] = {
|
||||
"metal: emergency: ",
|
||||
"metal: alert: ",
|
||||
"metal: critical: ",
|
||||
"metal: error: ",
|
||||
"metal: warning: ",
|
||||
"metal: notice: ",
|
||||
"metal: info: ",
|
||||
"metal: debug: ",
|
||||
};
|
||||
|
||||
va_start(args, format);
|
||||
vsnprintf(msg, sizeof(msg), format, args);
|
||||
va_end(args);
|
||||
|
||||
if (level <= METAL_LOG_EMERGENCY || level > METAL_LOG_DEBUG)
|
||||
level = METAL_LOG_EMERGENCY;
|
||||
|
||||
xil_printf("%s%s", level_strs[level], msg);
|
||||
}
|
||||
|
||||
static XIpiPsu IpiInst;
|
||||
|
||||
static XStatus IpiConfigure(XIpiPsu *const IpiInstPtr)
|
||||
{
|
||||
XStatus Status;
|
||||
XIpiPsu_Config *IpiCfgPtr;
|
||||
|
||||
/* Look Up the config data */
|
||||
IpiCfgPtr = XIpiPsu_LookupConfig(XPAR_XIPIPSU_0_DEVICE_ID);
|
||||
if (NULL == IpiCfgPtr) {
|
||||
Status = XST_FAILURE;
|
||||
LPERROR("%s ERROR in getting CfgPtr\n", __func__);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Init with the Cfg Data */
|
||||
Status = XIpiPsu_CfgInitialize(IpiInstPtr, IpiCfgPtr,
|
||||
IpiCfgPtr->BaseAddress);
|
||||
if (XST_SUCCESS != Status) {
|
||||
LPERROR("%s ERROR #%d in configuring IPI\n", __func__, Status);
|
||||
return Status;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
struct remoteproc * app_init(unsigned int cpu_id){
|
||||
struct metal_init_params metal_param = {
|
||||
.log_handler = app_log_handler,
|
||||
.log_level = METAL_LOG_DEBUG,
|
||||
};
|
||||
metal_init(&metal_param);
|
||||
|
||||
if (XST_SUCCESS != IpiConfigure(&IpiInst)) {
|
||||
LPERROR("Failed to config IPI instance\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (XST_SUCCESS != XPm_InitXilpm(&IpiInst)) {
|
||||
LPERROR("Failed to initialize PM\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return platform_create_proc(cpu_id);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright(c) 2019 Xilinx Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef PLATFORM_INFO_H_
|
||||
#define PLATFORM_INFO_H_
|
||||
|
||||
struct remoteproc * app_init(unsigned int cpu_id);
|
||||
#endif /* PLATFORM_INFO_H_ */
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* ZynqMP APU life cycle management remoteproc example implementation
|
||||
*
|
||||
* Copyright(c) 2019 Xilinx Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
static struct remoteproc *apu_rproc_init(struct remoteproc *rproc,
|
||||
struct remoteproc_ops *ops, void *arg)
|
||||
{
|
||||
struct rproc_priv *priv;
|
||||
unsigned int cpu_id = *((unsigned int *)arg);
|
||||
if(cpu_id < NODE_APU_0 || cpu_id > NODE_APU_1) {
|
||||
LPERROR("%s: invalid node id: %d \n\r",__func__, cpu_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LPRINTF("%s: node id: %d\n\r", __func__, cpu_id);
|
||||
priv = metal_allocate_memory(sizeof(*priv));
|
||||
if (!priv)
|
||||
return NULL;
|
||||
memset(priv, 0, sizeof(*priv));
|
||||
priv->rproc = rproc;
|
||||
priv->cpu_id = cpu_id;
|
||||
priv->rproc->ops = ops;
|
||||
metal_list_init(&priv->rproc->mems);
|
||||
priv->rproc->priv = priv;
|
||||
rproc->state = RPROC_READY;
|
||||
return priv->rproc;
|
||||
}
|
||||
|
||||
static void apu_rproc_remove(struct remoteproc *rproc)
|
||||
{
|
||||
struct rproc_priv *priv;
|
||||
|
||||
priv = (struct rproc_priv *)rproc->priv;
|
||||
metal_free_memory(priv);
|
||||
}
|
||||
|
||||
static void *apu_rproc_mmap(struct remoteproc *rproc,
|
||||
metal_phys_addr_t *pa, metal_phys_addr_t *da,
|
||||
size_t size, unsigned int attribute,
|
||||
struct metal_io_region **io)
|
||||
{
|
||||
struct remoteproc_mem *mem;
|
||||
metal_phys_addr_t lpa, lda, lda_end;
|
||||
|
||||
if ((!da || !pa) || (*da == METAL_BAD_PHYS && *pa == METAL_BAD_PHYS))
|
||||
return NULL;
|
||||
|
||||
LPRINTF("%s: pa=0x%x, da=0x%x, size=0x%x, atrribute=0x%x\n\r",
|
||||
__func__, *pa, *da, size, attribute);
|
||||
lda = *da;
|
||||
lpa = *pa;
|
||||
if (!attribute)
|
||||
attribute = NORM_SHARED_NCACHE | PRIV_RW_USER_RW;
|
||||
|
||||
|
||||
lda_end = lda + size;
|
||||
if (lda_end <= 0x80000000)
|
||||
XPm_RequestNode(NODE_DDR,PM_CAP_ACCESS,
|
||||
XPM_MIN_QOS,REQUEST_ACK_NO);
|
||||
if (lda >= 0xFFFC0000 && lda < 0xFFFD0000)
|
||||
XPm_RequestNode(NODE_OCM_BANK_0,PM_CAP_ACCESS,
|
||||
XPM_MIN_QOS,REQUEST_ACK_NO);
|
||||
if (lda <= 0xFFFDFFFF && lda_end >= 0xFFFD0000)
|
||||
XPm_RequestNode(NODE_OCM_BANK_1,PM_CAP_ACCESS,
|
||||
XPM_MIN_QOS,REQUEST_ACK_NO);
|
||||
if (lda <= 0xFFFEFFFF && lda_end >= 0xFFFE0000)
|
||||
XPm_RequestNode(NODE_OCM_BANK_2,PM_CAP_ACCESS,
|
||||
XPM_MIN_QOS,REQUEST_ACK_NO);
|
||||
if (lda_end >= 0xFFFF0000)
|
||||
XPm_RequestNode(NODE_OCM_BANK_3,PM_CAP_ACCESS,
|
||||
XPM_MIN_QOS,REQUEST_ACK_NO);
|
||||
|
||||
mem = metal_allocate_memory(sizeof(*mem));
|
||||
if (!mem)
|
||||
return NULL;
|
||||
mem->pa = lpa;
|
||||
mem->da = lda;
|
||||
|
||||
*io = metal_allocate_memory(sizeof(struct metal_io_region));
|
||||
if (!*io) {
|
||||
metal_free_memory(mem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This code only runs on the R5, which has a flat memory
|
||||
* space. Therefore, we use the same value for the physical
|
||||
* and virtual addresses we pass in to metal_io_init().
|
||||
*/
|
||||
metal_io_init(*io, (void *)mem->pa, &mem->pa, size,
|
||||
sizeof(metal_phys_addr_t)<<3, attribute, NULL);
|
||||
mem->io = *io;
|
||||
metal_list_add_tail(&rproc->mems, &mem->node);
|
||||
*pa = lpa;
|
||||
*da = lda;
|
||||
mem->size = size;
|
||||
return metal_io_phys_to_virt(*io, mem->pa);
|
||||
}
|
||||
|
||||
static int apu_rproc_start(struct remoteproc *rproc)
|
||||
{
|
||||
struct rproc_priv *priv;
|
||||
int ret;
|
||||
|
||||
priv = rproc->priv;
|
||||
ret = XPm_RequestWakeUp(priv->cpu_id, true,rproc->bootaddr,
|
||||
REQUEST_ACK_NO);
|
||||
if (ret != XST_SUCCESS) {
|
||||
LPRINTF("%s: Failed to start APU 0x%x, ret=0x%x\n\r",
|
||||
__func__, priv->cpu_id, ret);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apu_rproc_stop(struct remoteproc *rproc)
|
||||
{
|
||||
/* It is lacking a stop operation in the libPM */
|
||||
(void)rproc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apu_rproc_shutdown(struct remoteproc *rproc)
|
||||
{
|
||||
struct rproc_priv *priv;
|
||||
int ret;
|
||||
struct remoteproc_mem *mem;
|
||||
struct metal_list *node;
|
||||
|
||||
priv = rproc->priv;
|
||||
/* Delete all the registered remoteproc memories */
|
||||
metal_list_for_each(&rproc->mems, node) {
|
||||
struct metal_list *tmpnode;
|
||||
metal_phys_addr_t pa, pa_end;
|
||||
|
||||
mem = metal_container_of(node, struct remoteproc_mem, node);
|
||||
tmpnode = node;
|
||||
/* Release TCM resource */
|
||||
pa = mem->pa;
|
||||
pa_end = metal_io_phys(mem->io, metal_io_region_size(mem->io));
|
||||
if (pa_end <= 0x7FFFFFFF)
|
||||
XPm_ReleaseNode(NODE_DDR);
|
||||
if (pa >= 0xFFFC0000 && pa < 0xFFFD0000)
|
||||
XPm_ReleaseNode(NODE_OCM_BANK_0);
|
||||
if (pa <= 0xFFFDFFFF && pa_end >= 0xFFFD0000)
|
||||
XPm_ReleaseNode(NODE_OCM_BANK_1);
|
||||
if (pa <= 0xFFFEFFFF && pa_end >= 0xFFFE0000)
|
||||
XPm_ReleaseNode(NODE_OCM_BANK_2);
|
||||
if (pa_end >= 0xFFFF0000)
|
||||
XPm_ReleaseNode(NODE_OCM_BANK_3);
|
||||
|
||||
node = tmpnode->prev;
|
||||
metal_list_del(tmpnode);
|
||||
metal_free_memory(mem->io);
|
||||
metal_free_memory(mem);
|
||||
}
|
||||
ret = XPm_ForcePowerDown(priv->cpu_id, REQUEST_ACK_NO);
|
||||
if (ret != XST_SUCCESS)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct remoteproc_ops zynqmp_apu_rproc_ops = {
|
||||
.init = apu_rproc_init,
|
||||
.remove = apu_rproc_remove,
|
||||
.start = apu_rproc_start,
|
||||
.stop = apu_rproc_stop,
|
||||
.shutdown = apu_rproc_shutdown,
|
||||
.mmap = apu_rproc_mmap,
|
||||
};
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* ZynqMP RPU life cycle management remoteproc example implementation
|
||||
*
|
||||
* Copyright(c) 2019 Xilinx Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <common.h>
|
||||
|
||||
static struct remoteproc *rpu_rproc_init(struct remoteproc *rproc,
|
||||
struct remoteproc_ops *ops, void *arg)
|
||||
{
|
||||
struct rproc_priv *priv;
|
||||
unsigned int cpu_id = *((unsigned int *)arg);
|
||||
|
||||
if (cpu_id < NODE_RPU_0 || cpu_id > NODE_RPU_1) {
|
||||
LPERROR("%s: invalid node id: %d\n\r", __func__, cpu_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LPRINTF("%s: node id: %d\n\r", __func__, cpu_id);
|
||||
priv = metal_allocate_memory(sizeof(*priv));
|
||||
if (!priv)
|
||||
return NULL;
|
||||
memset(priv, 0, sizeof(*priv));
|
||||
priv->rproc = rproc;
|
||||
priv->cpu_id = cpu_id;
|
||||
priv->rproc->ops = ops;
|
||||
metal_list_init(&priv->rproc->mems);
|
||||
priv->rproc->priv = priv;
|
||||
rproc->state = RPROC_READY;
|
||||
return priv->rproc;
|
||||
}
|
||||
|
||||
static void rpu_rproc_remove(struct remoteproc *rproc)
|
||||
{
|
||||
struct rproc_priv *priv;
|
||||
|
||||
priv = (struct rproc_priv *)rproc->priv;
|
||||
metal_free_memory(priv);
|
||||
}
|
||||
|
||||
static void *rpu_rproc_mmap(struct remoteproc *rproc,
|
||||
metal_phys_addr_t *pa, metal_phys_addr_t *da,
|
||||
size_t size, unsigned int attribute,
|
||||
struct metal_io_region **io)
|
||||
{
|
||||
struct remoteproc_mem *mem;
|
||||
struct rproc_priv *priv;
|
||||
metal_phys_addr_t lpa, lda, lda_end;
|
||||
|
||||
priv = rproc->priv;
|
||||
|
||||
if ((!da || !pa) || (*da == METAL_BAD_PHYS && *pa == METAL_BAD_PHYS))
|
||||
return NULL;
|
||||
LPRINTF("%s: pa=0x%x, da=0x%x, size=0x%x, atrribute=0x%x\n\r",
|
||||
__func__, *pa, *da, size, attribute);
|
||||
lda = *da;
|
||||
lpa = *pa;
|
||||
if (!attribute)
|
||||
attribute = NORM_SHARED_NCACHE | PRIV_RW_USER_RW;
|
||||
|
||||
lda_end = lda + size;
|
||||
/* call xilpm request node for relevant memory */
|
||||
if (lda <= 0x40000) {
|
||||
if (priv->cpu_id == NODE_RPU_0 || priv->cpu_id == NODE_RPU) {
|
||||
lpa = 0xFFE00000 + lda;
|
||||
if (lda < 0x10000)
|
||||
XPm_RequestNode(NODE_TCM_0_A,PM_CAP_ACCESS,
|
||||
XPM_MIN_QOS,REQUEST_ACK_NO);
|
||||
if (lda <= 0x20000 && lda_end >= 0x10000)
|
||||
XPm_RequestNode(NODE_TCM_1_A,PM_CAP_ACCESS,
|
||||
XPM_MIN_QOS,REQUEST_ACK_NO);
|
||||
if (lda <= 0x30000 && lda_end >= 0x20000)
|
||||
XPm_RequestNode(NODE_TCM_0_B,PM_CAP_ACCESS,
|
||||
XPM_MIN_QOS,REQUEST_ACK_NO);
|
||||
if (lda <= 0x40000 && lda_end >= 0x30000)
|
||||
XPm_RequestNode(NODE_TCM_1_B,PM_CAP_ACCESS,
|
||||
XPM_MIN_QOS,REQUEST_ACK_NO);
|
||||
} else if (priv->cpu_id == NODE_RPU_1) {
|
||||
lpa = 0xFFE90000 + lda;
|
||||
if (lda < 0x10000)
|
||||
XPm_RequestNode(NODE_TCM_1_A,PM_CAP_ACCESS,
|
||||
XPM_MIN_QOS,REQUEST_ACK_NO);
|
||||
if (lda <= 0x30000 && lda_end >= 0x20000)
|
||||
XPm_RequestNode(NODE_TCM_1_B,PM_CAP_ACCESS,
|
||||
XPM_MIN_QOS,REQUEST_ACK_NO);
|
||||
} else {
|
||||
LPERROR("mmap failed: invalid cpu node: %d\r\n", priv->cpu_id);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mem = metal_allocate_memory(sizeof(*mem));
|
||||
if (!mem)
|
||||
return NULL;
|
||||
mem->pa = lpa;
|
||||
mem->da = lda;
|
||||
|
||||
*io = metal_allocate_memory(sizeof(struct metal_io_region));
|
||||
if (!*io) {
|
||||
metal_free_memory(mem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This code only runs on the R5, which has a flat memory
|
||||
* space. Therefore, we use the same value for the physical
|
||||
* and virtual addresses we pass in to metal_io_init().
|
||||
*/
|
||||
metal_io_init(*io, (void *)mem->pa, &mem->pa, size,
|
||||
sizeof(metal_phys_addr_t)<<3, attribute, NULL);
|
||||
mem->io = *io;
|
||||
metal_list_add_tail(&rproc->mems, &mem->node);
|
||||
*pa = lpa;
|
||||
*da = lda;
|
||||
mem->size = size;
|
||||
return metal_io_phys_to_virt(*io, mem->pa);
|
||||
}
|
||||
|
||||
static int rpu_rproc_start(struct remoteproc *rproc)
|
||||
{
|
||||
struct rproc_priv *priv;
|
||||
int ret;
|
||||
|
||||
priv = rproc->priv;
|
||||
ret = XPm_RequestWakeUp(priv->cpu_id, true, rproc->bootaddr,
|
||||
REQUEST_ACK_NO);
|
||||
if (ret != XST_SUCCESS) {
|
||||
LPRINTF("%s: Failed to start RPU 0x%x, ret=0x%x\n\r",
|
||||
__func__, priv->cpu_id, ret);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rpu_rproc_stop(struct remoteproc *rproc)
|
||||
{
|
||||
/* It is lacking a stop operation in the libPM */
|
||||
(void)rproc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rpu_rproc_shutdown(struct remoteproc *rproc)
|
||||
{
|
||||
struct rproc_priv *priv;
|
||||
int ret;
|
||||
struct remoteproc_mem *mem;
|
||||
struct metal_list *node;
|
||||
|
||||
priv = rproc->priv;
|
||||
/* Delete all the registered remoteproc memories */
|
||||
metal_list_for_each(&rproc->mems, node) {
|
||||
struct metal_list *tmpnode;
|
||||
metal_phys_addr_t pa, pa_end;
|
||||
|
||||
mem = metal_container_of(node, struct remoteproc_mem, node);
|
||||
tmpnode = node;
|
||||
/* Release TCM resource */
|
||||
pa = mem->pa;
|
||||
pa_end = metal_io_phys(mem->io, metal_io_region_size(mem->io));
|
||||
node = tmpnode->prev;
|
||||
metal_list_del(tmpnode);
|
||||
metal_free_memory(mem->io);
|
||||
metal_free_memory(mem);
|
||||
/* call xilpm release node for relevant memory */
|
||||
if (pa <= 0x40000) {
|
||||
if (priv->cpu_id == NODE_RPU_0 || priv->cpu_id == NODE_RPU) {
|
||||
if (pa < 0x10000)
|
||||
XPm_ReleaseNode(NODE_TCM_0_A);
|
||||
if (pa <= 0x20000 && pa_end >= 0x10000)
|
||||
XPm_ReleaseNode(NODE_TCM_1_A);
|
||||
if (pa <= 0x30000 && pa_end >= 0x20000)
|
||||
XPm_ReleaseNode(NODE_TCM_0_B);
|
||||
if (pa <= 0x40000 && pa_end >= 0x30000)
|
||||
XPm_ReleaseNode(NODE_TCM_1_B);
|
||||
} else if (priv->cpu_id == NODE_RPU_1) {
|
||||
if (pa < 0x10000)
|
||||
XPm_ReleaseNode(NODE_TCM_1_A);
|
||||
if (pa <= 0x30000 && pa_end >= 0x20000)
|
||||
XPm_ReleaseNode(NODE_TCM_1_B);
|
||||
} else {
|
||||
LPERROR("unmap failed: invalid cpu node: %d\r\n", priv->cpu_id);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ret = XPm_ForcePowerDown(priv->cpu_id, REQUEST_ACK_NO);
|
||||
if (ret != XST_SUCCESS)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct remoteproc_ops zynqmp_rpu_rproc_ops = {
|
||||
.init = rpu_rproc_init,
|
||||
.remove = rpu_rproc_remove,
|
||||
.start = rpu_rproc_start,
|
||||
.stop = rpu_rproc_stop,
|
||||
.shutdown = rpu_rproc_shutdown,
|
||||
.mmap = rpu_rproc_mmap,
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
collect (APP_COMMON_SOURCES platform_info.c)
|
||||
collect (APP_COMMON_SOURCES zynqmp_linux_r5_proc.c)
|
||||
collect (APP_INC_DIRS "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
|
||||
@@ -34,23 +34,28 @@
|
||||
#define RPU_CPU_ID 0 /* RPU remote CPU Index. We only talk to
|
||||
* one CPU in the exmaple. We set the CPU
|
||||
* index to 0. */
|
||||
#define IPI_CHN_BITMASK 0x00000100 /* IPI channel bit mask for IPI
|
||||
#ifdef versal
|
||||
#define IPI_CHN_BITMASK 0x08 /* IPI channel bit mask for IPI
|
||||
* from/to RPU0 */
|
||||
#define IPI_DEV_NAME "ff360000.ipi" /* IPI device name */
|
||||
#else
|
||||
#define IPI_CHN_BITMASK 0x00000100
|
||||
#define IPI_DEV_NAME "ff340000.ipi"
|
||||
#endif /* versal */
|
||||
#define DEV_BUS_NAME "platform" /* device bus name. "platform" bus
|
||||
* is used in Linux kernel for generic
|
||||
* devices */
|
||||
/* libmetal devices names used in the examples.
|
||||
* They are platform devices, you find them in Linux sysfs
|
||||
* sys/bus/platform/devices */
|
||||
#define IPI_DEV_NAME "ff340000.ipi" /* IPI device name */
|
||||
#define SHM_DEV_NAME "3ed20000.shm" /* shared device name */
|
||||
|
||||
#define RSC_MEM_PA 0x3ED20000UL
|
||||
#define RSC_MEM_SIZE 0x2000UL
|
||||
#define VRING_MEM_PA 0x3ED40000UL
|
||||
#define VRING_MEM_SIZE 0x8000UL
|
||||
#define SHARED_BUF_PA 0x3ED48000UL
|
||||
#define SHARED_BUF_SIZE 0x40000UL
|
||||
#define RSC_MEM_PA 0x3ED20000UL
|
||||
#define RSC_MEM_SIZE 0x2000UL
|
||||
#define VRING_MEM_PA 0x3ED40000UL
|
||||
#define VRING_MEM_SIZE 0x8000UL
|
||||
#define SHARED_BUF_PA 0x3ED48000UL
|
||||
#define SHARED_BUF_SIZE 0x40000UL
|
||||
|
||||
struct remoteproc_priv rproc_priv = {
|
||||
.ipi_name = IPI_DEV_NAME,
|
||||
|
||||
@@ -29,9 +29,6 @@
|
||||
|
||||
#define IPI_DEV_NAME "ipi_dev"
|
||||
#define IPI_BUS_NAME "generic"
|
||||
#define IPI_BASE_ADDR XPAR_XIPIPSU_0_BASE_ADDRESS /* IPI base address*/
|
||||
#define IPI_CHN_BITMASK 0x01000000 /* IPI channel bit mask for IPI from/to
|
||||
APU */
|
||||
|
||||
/* Cortex R5 memory attributes */
|
||||
#define DEVICE_SHARED 0x00000001U /* device, shareable */
|
||||
|
||||
@@ -17,7 +17,16 @@ extern "C" {
|
||||
#define PRIV_RW_USER_RW (0x00000003U<<8U) /* Full Access */
|
||||
|
||||
/* Interrupt vectors */
|
||||
#define IPI_IRQ_VECT_ID XPAR_XIPIPSU_0_INT_ID
|
||||
#ifdef versal
|
||||
#define IPI_IRQ_VECT_ID 63
|
||||
#define IPI_BASE_ADDR 0xFF340000 /* IPI base address*/
|
||||
#define IPI_CHN_BITMASK 0x0000020 /* IPI channel bit mask for IPI from/to
|
||||
APU */
|
||||
#else
|
||||
#define IPI_IRQ_VECT_ID XPAR_XIPIPSU_0_INT_ID
|
||||
#define IPI_BASE_ADDR XPAR_XIPIPSU_0_BASE_ADDRESS
|
||||
#define IPI_CHN_BITMASK 0x01000000
|
||||
#endif /* versal */
|
||||
|
||||
struct remoteproc_priv {
|
||||
const char *ipi_name; /**< IPI device name */
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
include(CheckSymbolExists)
|
||||
|
||||
collect (APP_COMMON_SOURCES helper.c)
|
||||
|
||||
set (_linker_script "${CMAKE_CURRENT_SOURCE_DIR}/linker_remote.ld")
|
||||
@@ -12,6 +14,23 @@ find_library(LIBXIL_LIB NAMES xil PATHS ${CMAKE_FIND_ROOT_PATH})
|
||||
get_filename_component(LIBXIL_LIB_DIR ${LIBXIL_LIB} DIRECTORY)
|
||||
collect(PROJECT_LIB_DIRS ${LIBXIL_LIB_DIR})
|
||||
|
||||
# check PM API for certain headers and set client version based
|
||||
CHECK_SYMBOL_EXISTS(XPAR_XILPM_ENABLED "xparameters.h" PM_FOUND)
|
||||
if(PM_FOUND)
|
||||
find_library(HAS_PM_LIB NAMES xilpm PATHS ${CMAKE_FIND_ROOT_PATH})
|
||||
collect (PROJECT_LIB_DEPS xilpm)
|
||||
CHECK_SYMBOL_EXISTS(versal "xparameters.h" VERSION_2_PM_CLIENT)
|
||||
if (VERSION_2_PM_CLIENT)
|
||||
collect (APP_EXTRA_C_FLAGS " -DVERSION_2_PM_CLIENT ")
|
||||
else()
|
||||
collect (APP_EXTRA_C_FLAGS " -DVERSION_1_PM_CLIENT ")
|
||||
endif(VERSION_2_PM_CLIENT)
|
||||
endif(PM_FOUND)
|
||||
|
||||
collect(PROJECT_LIB_DEPS xil)
|
||||
collect(PROJECT_LIB_DEPS c)
|
||||
collect(PROJECT_LIB_DEPS m)
|
||||
find_library(XILMEM_LIB NAMES xilmem PATHS ${CMAKE_FIND_ROOT_PATH})
|
||||
if(XILMEM_LIB)
|
||||
collect (PROJECT_LIB_DEPS xilmem)
|
||||
endif(XILMEM_LIB)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <metal/io.h>
|
||||
#include <metal/irq.h>
|
||||
#include <metal/shmem.h>
|
||||
#include <metal/scatterlist.h>
|
||||
#include <metal/utilities.h>
|
||||
#include <openamp/remoteproc.h>
|
||||
#include <openamp/rpmsg_virtio.h>
|
||||
@@ -58,20 +59,22 @@ struct remoteproc_priv {
|
||||
int shm_size;
|
||||
struct metal_io_region *shm_old_io;
|
||||
struct metal_io_region shm_new_io;
|
||||
struct metal_generic_shmem *metal_shm;
|
||||
struct metal_scatter_list *sg;
|
||||
struct remoteproc_mem shm;
|
||||
struct vring_ipi_info ipi;
|
||||
};
|
||||
|
||||
static struct remoteproc_priv rproc_priv_table [] = {
|
||||
{
|
||||
.shm_file = "openamp.shm",
|
||||
.shm_file = "linux_shm/openamp.shm",
|
||||
.shm_size = 0x80000,
|
||||
.ipi = {
|
||||
.path = "unixs:/tmp/openamp.event.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
.shm_file = "openamp.shm",
|
||||
.shm_file = "linux_shm/openamp.shm",
|
||||
.shm_size = 0x80000,
|
||||
.ipi = {
|
||||
.path = "unix:/tmp/openamp.event.0",
|
||||
@@ -228,6 +231,8 @@ linux_proc_init(struct remoteproc *rproc,
|
||||
struct remoteproc_priv *prproc = arg;
|
||||
struct metal_io_region *io;
|
||||
struct remoteproc_mem *shm;
|
||||
struct metal_generic_shmem *metal_shm = NULL;
|
||||
struct metal_scatter_list *sg = NULL;
|
||||
struct vring_ipi_info *ipi;
|
||||
int ret;
|
||||
|
||||
@@ -235,12 +240,20 @@ linux_proc_init(struct remoteproc *rproc,
|
||||
return NULL;
|
||||
rproc->priv = prproc;
|
||||
/* Create shared memory io */
|
||||
ret = metal_shmem_open(prproc->shm_file, prproc->shm_size, &io);
|
||||
ret = metal_shmem_open(prproc->shm_file, prproc->shm_size, 0, &metal_shm);
|
||||
if (ret) {
|
||||
printf("Failed to init rproc, failed to open shm %s.\r\n",
|
||||
prproc->shm_file);
|
||||
return NULL;
|
||||
}
|
||||
prproc->metal_shm = metal_shm;
|
||||
sg = metal_shmem_mmap(metal_shm, prproc->shm_size);
|
||||
if (sg == NULL) {
|
||||
printf("Failed mmap shmem with libmetal.\n");
|
||||
goto err;
|
||||
}
|
||||
prproc->sg = sg;
|
||||
io = sg->ios;
|
||||
prproc->shm_old_io = io;
|
||||
shm = &prproc->shm;
|
||||
shm->pa = 0;
|
||||
@@ -270,6 +283,12 @@ linux_proc_init(struct remoteproc *rproc,
|
||||
return rproc;
|
||||
|
||||
err:
|
||||
if (sg != NULL) {
|
||||
metal_shmem_munmap(metal_shm, sg);
|
||||
}
|
||||
if (metal_shm != NULL) {
|
||||
metal_shmem_close(metal_shm);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -278,7 +297,6 @@ static void linux_proc_remove(struct remoteproc *rproc)
|
||||
{
|
||||
struct remoteproc_priv *prproc;
|
||||
struct vring_ipi_info *ipi;
|
||||
struct metal_io_region *io;
|
||||
|
||||
if (!rproc)
|
||||
return;
|
||||
@@ -293,10 +311,11 @@ static void linux_proc_remove(struct remoteproc *rproc)
|
||||
}
|
||||
|
||||
/* Close shared memory */
|
||||
io = prproc->shm_old_io;
|
||||
if (io && io->ops.close) {
|
||||
io->ops.close(io);
|
||||
prproc->shm_old_io = NULL;
|
||||
if (prproc->metal_shm) {
|
||||
if (prproc->sg) {
|
||||
metal_shmem_munmap(prproc->metal_shm, prproc->sg);
|
||||
}
|
||||
metal_shmem_close(prproc->metal_shm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,19 +390,29 @@ static int platform_slave_setup_resource_table(const char *shm_file,
|
||||
metal_phys_addr_t rsc_pa)
|
||||
{
|
||||
struct metal_io_region *io;
|
||||
struct metal_generic_shmem *metal_shm = NULL;
|
||||
struct metal_scatter_list *sg = NULL;
|
||||
void *rsc_shm;
|
||||
int ret;
|
||||
|
||||
ret = metal_shmem_open(shm_file, shm_size, &io);
|
||||
/* Get shared memory io */
|
||||
ret = metal_shmem_open(shm_file, shm_size, 0, &metal_shm);
|
||||
if (ret) {
|
||||
printf("Failed to init rproc, failed to open shm %s.\r\n",
|
||||
printf("Failed to setup rsc table, failed to open shm %s.\r\n",
|
||||
shm_file);
|
||||
return -1;
|
||||
}
|
||||
sg = metal_shmem_mmap(metal_shm, shm_size);
|
||||
if (sg == NULL) {
|
||||
printf("Failed to setup rsc table, mmap with libmetal failed.\r\n");
|
||||
metal_shmem_close(metal_shm);
|
||||
return -1;
|
||||
}
|
||||
io = sg->ios;
|
||||
rsc_shm = metal_io_virt(io, rsc_pa);
|
||||
memcpy(rsc_shm, rsc_table, rsc_size);
|
||||
io->ops.close(io);
|
||||
free(io);
|
||||
metal_shmem_munmap(metal_shm, sg);
|
||||
metal_shmem_close(metal_shm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,11 @@ if (WITH_APPS)
|
||||
endif (WITH_PROXY)
|
||||
endif (WITH_APPS)
|
||||
|
||||
# LOAD_FW only allowed for R5, otherwise turn off
|
||||
if (NOT ${MACHINE} STREQUAL "zynqmp_r5")
|
||||
set (WITH_LOAD_FW OFF)
|
||||
endif(NOT ${MACHINE} STREQUAL "zynqmp_r5")
|
||||
|
||||
option (WITH_VIRTIO_MASTER "Build with virtio master enabled" ON)
|
||||
option (WITH_VIRTIO_SLAVE "Build with virtio slave enabled" ON)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user