diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ea17e24adf3ed14d0a040e2662f966e793afcc9..88c5cc33f46e58a4feae2c6132ddf025304dbedf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,9 @@ endif() ## build MICA library set(MICA_LIB mica) add_subdirectory(${CMAKE_SOURCE_DIR}/library) +if (NOT ${ALLOC_EXTRA_MEM} STREQUAL "") + target_compile_options(${MICA_LIB} PUBLIC -DALLOC_EXTRA_MEM=${ALLOC_EXTRA_MEM}) +endif() ## build MICA client add_subdirectory(${CMAKE_SOURCE_DIR}/mica) diff --git a/README.md b/README.md index 84cc9e440345efcd5e57c5708ae2703dac7e3eb0..dd96130c84f7f796e20189f6f1ec0d77a1c0f05a 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,8 @@ mcs支持两种构建安装方式: cmake -S . -B build ## 注:若希望构建带调试信息的二进制,请配置 CMAKE_BUILD_TYPE,例如: ## cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug + ## 注:若希望使用额外的共享内存,请确保预留足够内存,并配置ALLOC_EXTRA_MEM,例如: + ## cmake -S . -B build -DALLOC_EXTRA_MEM=0x1100000UL cd build make diff --git a/library/include/remoteproc/mica_rsc.h b/library/include/remoteproc/mica_rsc.h index 5f7eccea562df672d8e128a455ce1ab5c387599e..20c559316dbde99238bcda63d1c8c1747335d309 100644 --- a/library/include/remoteproc/mica_rsc.h +++ b/library/include/remoteproc/mica_rsc.h @@ -18,6 +18,7 @@ extern "C" { * * Range: [RSC_VENDOR_START, RSC_VENDOR_END] * @RSC_VENDOR_EPT_TABLE: List of bound endpoints + * @RSC_PHY_MEM: continuous physical memory * * For more details regarding a specific resource type, please see its * dedicated structure below. @@ -30,6 +31,9 @@ extern "C" { */ enum mica_resource_type { RSC_VENDOR_EPT_TABLE = 128, + RSC_UNIPROTON_LOG_MEM = 256, + RSC_UNIPROTON_RESEVERD_START = 257, + RSC_UNIPROTON_RESEVERD_END = 271, }; /** @@ -57,6 +61,23 @@ struct fw_rsc_ept { struct ept_info endpoints[MAX_NUM_OF_EPTS]; } METAL_PACKED_END; +/** + * struct fw_rsc_log_phymem - share memory for log + * @pa: physical address of allocated memory + * @len: requested length of memory + + * Client can request physical memory and treated it as share memory for the use of UniProton log system. + * Client can not specify the physical address of requested memory by @pa. + */ +METAL_PACKED_BEGIN +struct fw_rsc_log_phymem { + uint32_t type; + uint32_t pa; + uint32_t va; + uint32_t len; + char name[RPMSG_NAME_SIZE]; +} METAL_PACKED_END; + /** * handle_mica_rsc - Process our custom rsctable entries */ diff --git a/library/remoteproc/baremetal_rproc.c b/library/remoteproc/baremetal_rproc.c index c2c551b16713058a08bd9fdee4008d05cc74e221..f4651f459cd59efb5b4a5300f38a6f8f3657fae2 100644 --- a/library/remoteproc/baremetal_rproc.c +++ b/library/remoteproc/baremetal_rproc.c @@ -273,7 +273,14 @@ static int rproc_config(struct remoteproc *rproc, void *data) } client = metal_container_of(rproc, struct mica_client, rproc); + +#if defined(ALLOC_EXTRA_MEM) && (ALLOC_EXTRA_MEM > 0) + DEBUG_PRINT("alloc extra shm mem %u", (uint32_t)ALLOC_EXTRA_MEM); + ret = init_shmem_pool(client, info.phy_addr + (client->cpu_id * SHM_POOL_SIZE), SHM_POOL_SIZE + ALLOC_EXTRA_MEM); +#else ret = init_shmem_pool(client, info.phy_addr + (client->cpu_id * SHM_POOL_SIZE), SHM_POOL_SIZE); +#endif + if (ret) { syslog(LOG_ERR, "init shared memory pool failed, err %d\n", ret); return ret; diff --git a/library/remoteproc/mica_rsc_table.c b/library/remoteproc/mica_rsc_table.c index d7776193714471739d4807fe038ce99c07e6b6e5..a731e1ea61a92e6797acc4cd10b4c2e9d4e71a3d 100644 --- a/library/remoteproc/mica_rsc_table.c +++ b/library/remoteproc/mica_rsc_table.c @@ -5,6 +5,9 @@ */ #include +#include +#include +#include #include #include @@ -12,30 +15,84 @@ #include #include +#include "memory/shm_pool.h" + +/* Uniproton log读取设备 */ +#define LOG_DEVICE_NAME "/dev/logW" +#define MAGIC_NUMBER 'L' +#define IOC_LOG_START _IOW(MAGIC_NUMBER, 0, int) +#define IOC_LOG_STOP _IOW(MAGIC_NUMBER, 1, int) + +int rsc_update_log_mem_table(struct remoteproc *rproc, void *rsc); int handle_mica_rsc(struct remoteproc *rproc, void *rsc, size_t len) { int i; uint32_t rsc_type; + struct ept_info *ept; + struct fw_rsc_ept *ept_rsc = rsc; rsc_type = ((struct fw_rsc_vendor *)rsc)->type; switch (rsc_type) { - case RSC_VENDOR_EPT_TABLE: - { - struct fw_rsc_ept *ept_rsc = rsc; - struct ept_info *ept; - - for (i = 0; i < ept_rsc->num_of_epts; i++) { - ept = &ept_rsc->endpoints[i]; - if (ept->addr != 0) - register_remote_ept(ept->name, ept->addr, ept->dest_addr); - } - break; + case RSC_VENDOR_EPT_TABLE: + for (i = 0; i < ept_rsc->num_of_epts; i++) { + ept = &ept_rsc->endpoints[i]; + if (ept->addr != 0) + register_remote_ept(ept->name, ept->addr, ept->dest_addr); + } + break; + case RSC_UNIPROTON_LOG_MEM: + return rsc_update_log_mem_table(rproc, rsc); + default: + break; + } + return 0; +} + +int rsc_update_log_mem_table(struct remoteproc *rproc, void *rsc) +{ + void *buf; + metal_phys_addr_t da, pa; + size_t bufsz; + struct fw_rsc_log_phymem *mem_rsc; + int ret, fd; + uintptr_t phyAddr; + + if (rproc == NULL || rsc == NULL) { + return -EFAULT; + } + mem_rsc = (struct fw_rsc_log_phymem *)rsc; + pa = mem_rsc->pa; + bufsz = mem_rsc->len; + struct mica_client *client = metal_container_of(rproc, struct mica_client, rproc); + if (bufsz == 0) { + return 0; + } + buf = alloc_shmem_region(client, 0, bufsz); + syslog(LOG_INFO, "alloc log buf:%p, size:0x%lx\n", buf, bufsz); + if (!buf) { + return -ENOMEM; + } + memset(buf, 0, bufsz); + pa = shm_pool_virt_to_phys(client, buf); + da = METAL_BAD_PHYS; + (void *)remoteproc_mmap(rproc, &pa, &da, bufsz, 0, NULL); + DEBUG_PRINT("alloc phymem, paddr: 0x%lx, daddr: 0x%lx, vaddr: %p, size: 0x%lx\n", pa, da, buf, bufsz); + mem_rsc->pa = da; + + fd = open(LOG_DEVICE_NAME, O_RDWR | O_SYNC); + if (fd < 0) { + syslog(LOG_ERR, "open %s device failed, err %d\n", LOG_DEVICE_NAME, fd); + return fd; } - default: - break; + phyAddr = (uintptr_t)da; + ret = ioctl(fd, IOC_LOG_START, &phyAddr); + if (ret < 0) { + syslog(LOG_ERR, "unable to start log worker %d\n", ret); + return ret; } + metal_cache_flush(mem_rsc, sizeof(struct fw_rsc_log_phymem)); return 0; }