diff --git a/apps/BUILD.gn b/apps/BUILD.gn index bf35c91afa8d17d81d3098f8e1479316b52fc184..746ffc70b00c348ae66aa43db218a7515e56e09d 100644 --- a/apps/BUILD.gn +++ b/apps/BUILD.gn @@ -37,6 +37,8 @@ group("apps") { "mksh", "shell", "toybox", + "rpmsg-sample-ping", + "rpmsg-sample-echo", ] } diff --git a/apps/config.mk b/apps/config.mk index 51e9e21991a2958641b78257593bf0b9d10025d8..bdbf36c60135da60e38c84ec175cbffd10e2e48a 100644 --- a/apps/config.mk +++ b/apps/config.mk @@ -56,6 +56,8 @@ ifeq ($(LOSCFG_SHELL), y) APP_SUBDIRS += shell APP_SUBDIRS += mksh APP_SUBDIRS += toybox +APP_SUBDIRS += rpmsg-sample-ping +APP_SUBDIRS += rpmsg-sample-echo endif ifeq ($(LOSCFG_USER_INIT_DEBUG), y) diff --git a/apps/rpmsg-sample-echo/BUILD.gn b/apps/rpmsg-sample-echo/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..81abb7806cf13d45d16f8b90fbcbde93ab3f1a9a --- /dev/null +++ b/apps/rpmsg-sample-echo/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., 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: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. 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. +# +# 3. Neither the name of the copyright holder 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 HOLDER 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. + +import("//kernel/liteos_a/liteos.gni") + +executable("rpmsg-sample-echo") { + sources = [ + "src/rpmsg-sample-echo.c", + ] + + deps = [ "$LITEOSTHIRDPARTY/open-amp:libopenamp_static" ] + + include_dirs = [ "include" ] +} diff --git a/apps/rpmsg-sample-echo/Makefile b/apps/rpmsg-sample-echo/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4c2c565fb706e66410726d951c604f8b93624b35 --- /dev/null +++ b/apps/rpmsg-sample-echo/Makefile @@ -0,0 +1,50 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., 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: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. 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. +# +# 3. Neither the name of the copyright holder 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 HOLDER 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. + +include $(APPSTOPDIR)/config.mk + +APP_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS = $(wildcard src/*.c) + +LOCAL_INCLUDE := \ + -I include \ + -I $(LITEOSTHIRDPARTY)/open-amp/porting/liteos_a/open-amp/apps/system/liteos_a/machine/generic \ + -I $(LITEOSTHIRDPARTY)/open-amp/porting/liteos_a/open-amp/lib/include \ + -I $(LITEOSTHIRDPARTY)/open-amp/build/libmetal/lib/include \ + -I $(LITEOSTHIRDPARTY)/open-amp/build/musl \ + -I $(LITEOSTHIRDPARTY)/open-amp/build/sysfs/include + +LOCAL_FLAGS += $(LOCAL_INCLUDE) + +CFLAGS += -D_GNU_SOURCE + +LDFLAGS += -L$(LITEOSTHIRDPARTY)/../out/hispark_taurus/ipcamera_hispark_taurus/libs/ -lopenamp_static + +include $(APP) diff --git a/apps/rpmsg-sample-echo/src/rpmsg-sample-echo.c b/apps/rpmsg-sample-echo/src/rpmsg-sample-echo.c new file mode 100644 index 0000000000000000000000000000000000000000..ce5bd305c09922f02afec3235d4bd173c47e3707 --- /dev/null +++ b/apps/rpmsg-sample-echo/src/rpmsg-sample-echo.c @@ -0,0 +1,137 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * This is a sample demonstration application that showcases usage of rpmsg + * This application is meant to run on the remote CPU running baremetal code. + * This application allows to check the compatibility with linux OS running on + * the host CPU. For this it echo MSG_LIMIT time message sent by the rpmsg + * sample client available in linux kernel distribution. + */ + +#include +#include +#include +#include "platform_info.h" + +#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__) +#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__) + + +#define RPMSG_SERV_NAME "rpmsg-client-sample" +#define MSG_LIMIT 100 + +static struct rpmsg_endpoint lept; +static int shutdown_req = 0; + +/*-----------------------------------------------------------------------------* + * RPMSG endpoint callbacks + *-----------------------------------------------------------------------------*/ +static int rpmsg_endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len, + uint32_t src, void *priv) +{ + (void)priv; + (void)src; + static uint32_t count = 0; + char payload[RPMSG_BUFFER_SIZE]; + + /* Send data back MSG_LIMIT time to host */ + memset(payload, 0, RPMSG_BUFFER_SIZE); + memcpy(payload, data, len); + if (++count <= MSG_LIMIT) { + LPRINTF("echo message number %u: %s\r\n", + (unsigned int)count, payload); + if (rpmsg_send(ept, (char *)data, len) < 0) { + LPERROR("rpmsg_send failed\r\n"); + goto destroy_ept; + } + + if (count == MSG_LIMIT) { + goto destroy_ept; + } + } + return RPMSG_SUCCESS; + +destroy_ept: + shutdown_req = 1; + return RPMSG_SUCCESS; +} + +static void rpmsg_service_unbind(struct rpmsg_endpoint *ept) +{ + (void)ept; + LPRINTF("unexpected Remote endpoint destroy\r\n"); + shutdown_req = 1; +} + +/*-----------------------------------------------------------------------------* + * Application + *-----------------------------------------------------------------------------*/ +int app(struct rpmsg_device *rdev, void *priv) +{ + int ret; + + /* Initialize RPMSG framework */ + LPRINTF("Try to create rpmsg endpoint.\r\n"); + + ret = rpmsg_create_ept(&lept, rdev, RPMSG_SERV_NAME, + RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, + rpmsg_endpoint_cb, rpmsg_service_unbind); + if (ret) { + LPERROR("Failed to create endpoint.\r\n"); + return -1; + } + + LPRINTF("Successfully created rpmsg endpoint.\r\n"); + while (1) { + platform_poll(priv); + /* we got a shutdown request, exit */ + if (shutdown_req) { + break; + } + } + rpmsg_destroy_ept(&lept); + + return 0; +} + +/*-----------------------------------------------------------------------------* + * Application entry point + *-----------------------------------------------------------------------------*/ +int main(int argc, char *argv[]) +{ +#ifdef KERNEL_PRIMARY_CORE + return -1; +#endif + + void *platform; + struct rpmsg_device *rpdev; + int ret; + + LPRINTF("Starting application...\r\n"); + + /* Initialize platform */ + ret = platform_init(argc, argv, &platform); + if (ret) { + LPERROR("Failed to initialize platform.\r\n"); + ret = -1; + } else { + rpdev = platform_create_rpmsg_vdev(platform, 0, + VIRTIO_DEV_DEVICE, + NULL, NULL); + if (!rpdev) { + LPERROR("Failed to create rpmsg virtio device.\r\n"); + ret = -1; + } else { + app(rpdev, platform); + platform_release_rpmsg_vdev(rpdev, platform); + ret = 0; + } + } + + LPRINTF("Stopping application...\r\n"); + platform_cleanup(platform); + + return ret; +} diff --git a/apps/rpmsg-sample-ping/BUILD.gn b/apps/rpmsg-sample-ping/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..2655a87284b957b39a2c356e71fd8392ff9c87bb --- /dev/null +++ b/apps/rpmsg-sample-ping/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., 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: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. 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. +# +# 3. Neither the name of the copyright holder 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 HOLDER 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. + +import("//kernel/liteos_a/liteos.gni") + +executable("rpmsg-sample-ping") { + sources = [ + "src/rpmsg-sample-ping.c", + ] + + deps = [ "$LITEOSTHIRDPARTY/open-amp:libopenamp_static" ] + + include_dirs = [ "include" ] +} diff --git a/apps/rpmsg-sample-ping/CMakeLists.txt b/apps/rpmsg-sample-ping/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..69a1e34a04eba8c25b3d240821d4b9a071714808 --- /dev/null +++ b/apps/rpmsg-sample-ping/CMakeLists.txt @@ -0,0 +1,42 @@ + +set (_cflags "${CMAKE_C_FLAGS} ${APP_EXTRA_C_FLAGS} -fdata-sections -ffunction-sections") +set (_fw_dir "${APPS_SHARE_DIR}") + +collector_list (_list PROJECT_INC_DIRS) +collector_list (_app_list APP_INC_DIRS) +include_directories (${_list} ${_app_list} ${CMAKE_CURRENT_SOURCE_DIR}) + +collector_list (_list PROJECT_LIB_DIRS) +collector_list (_app_list APP_LIB_DIRS) +link_directories (${_list} ${_app_list}) + +get_property (_linker_opt GLOBAL PROPERTY APP_LINKER_OPT) +collector_list (_deps PROJECT_LIB_DEPS) + +set (OPENAMP_LIB open_amp) + +foreach (_app rpmsg-sample-echo rpmsg-sample-ping) + collector_list (_sources APP_COMMON_SOURCES) + list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/${_app}.c") + + if (WITH_SHARED_LIB) + add_executable (${_app}-shared ${_sources}) + target_link_libraries (${_app}-shared ${OPENAMP_LIB}-shared ${_deps}) + install (TARGETS ${_app}-shared RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif (WITH_SHARED_LIB) + + if (WITH_STATIC_LIB) + if (${PROJECT_SYSTEM} STREQUAL "linux") + add_executable (${_app}-static ${_sources}) + target_link_libraries (${_app}-static ${OPENAMP_LIB}-static ${_deps}) + install (TARGETS ${_app}-static RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + else (${PROJECT_SYSTEM}) + 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 ${_linker_opt} -Wl,--start-group ${OPENAMP_LIB}-static ${_deps} -Wl,--end-group) + + install (TARGETS ${_app}.out RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif (${PROJECT_SYSTEM} STREQUAL "linux" ) + endif (WITH_STATIC_LIB) +endforeach(_app) diff --git a/apps/rpmsg-sample-ping/Makefile b/apps/rpmsg-sample-ping/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..b765262128869c66247ecf67cc3824adcfd0faba --- /dev/null +++ b/apps/rpmsg-sample-ping/Makefile @@ -0,0 +1,48 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., 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: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. 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. +# +# 3. Neither the name of the copyright holder 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 HOLDER 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. + +include $(APPSTOPDIR)/config.mk + +APP_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS = $(wildcard src/*.c) + +LOCAL_INCLUDE := \ + -I include \ + -I $(LITEOSTHIRDPARTY)/open-amp/porting/liteos_a/open-amp/apps/system/liteos_a/machine/generic \ + -I $(LITEOSTHIRDPARTY)/open-amp/porting/liteos_a/open-amp/lib/include \ + -I $(LITEOSTHIRDPARTY)/open-amp/build/libmetal/lib/include \ + -I $(LITEOSTHIRDPARTY)/open-amp/build/musl \ + -I $(LITEOSTHIRDPARTY)/open-amp/build/sysfs/include + +LOCAL_FLAGS += $(LOCAL_INCLUDE) + +LDFLAGS += -L$(LITEOSTHIRDPARTY)/../out/hispark_taurus/ipcamera_hispark_taurus/libs/ -lopenamp_static + +include $(APP) diff --git a/apps/rpmsg-sample-ping/src/rpmsg-sample-ping.c b/apps/rpmsg-sample-ping/src/rpmsg-sample-ping.c new file mode 100644 index 0000000000000000000000000000000000000000..361a7fb205a22185ec4eeac82207cd4f9e3ae198 --- /dev/null +++ b/apps/rpmsg-sample-ping/src/rpmsg-sample-ping.c @@ -0,0 +1,427 @@ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SHM_ADDR 0x80800000 - (2 * 1024 * 1024) + +#define cmd_notify_start_read 1 +#define cmd_notify_shutdown 2 +#define cmd_notify_wakeup 3 + + +static int waitInput(void); + + +int accessMethod1(int argc, char *argv[]) +{ + printf("[user]accessMethod1:now call open/read/write for /dev/uio0 turn 1\n\n\n"); + + int fd; + fd = open("/dev/uio0", O_RDWR); + if (fd > 0) + { + printf("[user]accessMethod1:open fd = %d\n", fd); + + + //mmap(SHM_ADDR, xxxxxxx); + char InBuf[30] = {0}; + int len = read(fd, &InBuf[0], 10); + printf("[user]accessMethod1:read len=%d, InBuf=%s\n", len, InBuf); + + const char outBuf[30] = "123456789"; + int writeLen = write(fd, &outBuf[0], 10); + printf("[user]accessMethod1:write buf=[%s], len=%d\n", outBuf, writeLen); + close(fd); + }else{ + printf("[user]accessMethod1:open failed, fd = %d\n", fd); + } + + printf("[user]accessMethod1:now call open/read/write for /dev/uio0 turn 2\n\n\n"); + fd = open("/dev/uio0", O_RDWR); + if (fd > 0) + { + printf("[user]accessMethod1:open fd = %d\n", fd); + + + //mmap(SHM_ADDR, xxxxxxx); + char InBuf[30] = {0}; + int len = read(fd, &InBuf[0], 10); + printf("[user]accessMethod1:read len=%d, InBuf=%s\n", len, InBuf); + + const char outBuf[30] = "123456789"; + int writeLen = write(fd, &outBuf[0], 10); + printf("[user]accessMethod1:write buf=[%s], len=%d\n", outBuf, writeLen); + close(fd); + }else{ + printf("[user]accessMethod1:open failed, fd = %d\n", fd); + } + + + + printf("[user]next: open non-exist dev as /dev/myuio0..............\n"); + fd = open("/dev/myuio0", O_RDONLY); + printf("[user]done: open non-exist dev as /dev/myuio0, fd=%d\n", fd); + + return 0; + +#if 0 + void *platform; + int ret; + + /* Initialize platform */ + ret = platform_init(argc, argv, &platform); + + return ret; +#endif +} + +int mmapEcho(char *devname) +{ + printf("[user]mmapEcho:now call open/read/write for /dev/%s. (O_RDWR)\n\n\n", devname); + + int fd; + int readSz; + void *src; + readSz = 20; + char devFullPath[128]; + sprintf(devFullPath, "/dev/%s", devname); + + fd = open(devFullPath, O_RDWR); + if (fd > 0) { + printf("[user]mmapEcho:open fd = %d, mmap with PROT_READ,readSz=%d..................\n", fd,readSz); + src = mmap(0, readSz, PROT_READ, MAP_SHARED, fd, 0); + if (src == MAP_FAILED) { + printf("[user]mmapEcho:mmap error for input\n"); + return -1; + } + + char bufferRead[30] = {0}; + memcpy(bufferRead, src, readSz); + printf("[user]mmapEcho:i read via SHARE_MEMORY result as %s,readSz=%d\n", bufferRead,readSz); + + munmap(src, readSz); + close(fd); + } + return 0; +} + + +int mmapSendMsg(char *devname) +{ + printf("[user]mmapSendMsg:now call open/read/write for /dev/%s. (O_RDWR)\n\n\n", devname); + + int fd; + int mmapSize = 3 * 4096; + int writeSz; + void *dst; + writeSz = 20; + char devFullPath[128]; + sprintf(devFullPath, "/dev/%s", devname); + fd= open(devFullPath, O_RDWR); + if (fd > 0) { + printf("[user]mmapSendMsg:open fd = %d,next mmap with PROT_READ | PROT_WRITE,mmapSize=%d..................\n", fd, mmapSize); + dst = mmap(0, mmapSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (dst == MAP_FAILED) { + printf("[user]mmapSendMsg:mmap error for input\n"); + return -1; + } + + char bufferWrite[20] = "i am mmapSendMsg"; + memcpy(dst, bufferWrite, writeSz); + printf("[user]mmapSendMsg:i write to SHARE_MEMORY, content is %s,writeSz=%d......\n", bufferWrite, writeSz); + + munmap(dst, writeSz); + close(fd); + } + return 0; +} + +int openUioDevice(char *devname) +{ + int fd; + char devFullPath[128]; + sprintf(devFullPath, "/dev/%s", devname); + fd= open(devFullPath, O_RDWR); + if (fd > 0) { + printf("[user]%s:open fd = %d,\n", __FUNCTION__, fd); + return fd; + } + return -1; +} + +int shutdownMainProcess(void) +{ + return 0; +} + +int shutdownsecondaryProcess(void) +{ + return 0; +} + +int showCpuAffinity(void) +{ + int ret; + int cpus = 0; + int cpuId; + int coreId; + cpu_set_t mask; + int processMask = 0; + + //cpus = sysconf(_SC_NPROCESSORS_ONLN); + //printf("showCpuAffinity:cpus: %d\n", cpus); + cpus = 2; + + CPU_ZERO( &mask ); + + ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &mask); + for (cpuId = 0; cpuId < 4; cpuId++) + { + if (mask.__bits[cpuId] > 0) + { + printf("showCpuAffinity:show mask:pid %d: bind to cpu-%d:core=%#lx\n", getpid(), cpuId, mask.__bits[cpuId]); + } + } + + printf("showCpuAffinity:show details--------\n\n"); + for (coreId = 0; coreId < cpus; coreId++) + { + ret = CPU_ISSET(coreId, &mask); + if (ret) + { + processMask |= 1< 0) + { + printf("showCpuAffinity:--------show mask:pid %d: bind to cpu-%d:core=%#lx\n", getpid(), cpuId, mask.__bits[cpuId]); + } + } + break; + } + processMask = 0; + } + return coreId; +} + + +// open uio0, +// mmap +// register 本侧中断处理 +// write data 写入数据为 hello +// 通知另一侧读取 ioctl +int mainCoreProcess(void) +{ + int INTFd; + int dataFd; + void *dst; + int ret; + int mmapSize = 256; + int writeSz = 20; + int actualCoreId; + printf("%s:[pid %d] start run...................\n\n\n", __FUNCTION__, getpid()); + + + cpu_set_t cpuset; + CPU_ZERO(&cpuset);/* 初始化set集,将set置为空 */ + CPU_SET(0, &cpuset); /* cpu0 */ + ret = sched_setaffinity(getpid(), sizeof(struct cpu_set_t), &cpuset); + if (ret == -1) { + printf("Set CPU affinity failue, ERROR:%s\n", strerror(errno)); + return -1; + } + + actualCoreId = showCpuAffinity(); + printf("%s:core=%d:[pid %d] confirm sched_getaffinity(0) result \n", __FUNCTION__, actualCoreId, getpid()); + + // open uio1, + char *uioIntDevname = "uio1"; + INTFd = openUioDevice(uioIntDevname); + printf("%s:core=%d:[pid %d] open INT Device %s, return fd=%d\n", __FUNCTION__, actualCoreId, getpid(), uioIntDevname, INTFd); + + // register 本侧中断处理 + printf("%s:core=%d:[pid %d] write to [register irq] turn on irq calling ........\n", __FUNCTION__, actualCoreId, getpid()); + const char outBuf[30] = "123456789"; + int writeLen = write(INTFd, &outBuf[0], 10); + printf("%s:core=%d:[pid %d] write to [register irq] turn on irq ok,writeLen=%d\n", + __FUNCTION__, actualCoreId, getpid(), writeLen); + + // mmap + // open uio1, + char *uioDataDevname = "uio0"; + dataFd = openUioDevice(uioDataDevname); + printf("%s:core=%d:[pid %d] open data Device %s, return fd=%d\n", __FUNCTION__, actualCoreId, getpid(), uioDataDevname, dataFd); + + printf("%s:core=%d:[pid %d] mmap calling (READ|WRITE)........\n", __FUNCTION__, actualCoreId, getpid()); + dst = mmap(0, mmapSize, PROT_READ | PROT_WRITE, MAP_SHARED, dataFd, 0); + + // write data 写入数据为 hello + char bufferWrite[20] = "i am mmapSendMsg"; + memcpy(dst, bufferWrite, writeSz); + printf("%s:core=%d:[pid %d]i memcpy to SHARE_MEMORY, content is %s,writeSz=%d ok\n", __FUNCTION__, actualCoreId, getpid(), bufferWrite, writeSz); + + // 通知另一侧读取 ioctl + int cmd = cmd_notify_start_read; + int flag = 0; + printf("%s:core=%d:[pid %d] ioctl to INTFd %d, calling to notify sem-read allow........\n", __FUNCTION__, actualCoreId, getpid(), INTFd); + ioctl(INTFd, cmd, flag); + printf("%s:core=%d:[pid %d] ioctl to INTFd %d, notify sem-read allow ok\n", __FUNCTION__, actualCoreId, getpid(), INTFd); + + return 0; +} + +// open uio0 +// mmap +// register 本侧中断处理 +// read data +// write data 写入数据为(ACK) +// 通知另一侧读取 ioctl +int secondaryCoreProcess(void) +{ + printf("%s:[pid %d] start run...................\n\n\n", __FUNCTION__, getpid()); + int INTFd; + int dataFd; + void *src; + int ret; + int mmapSize = 256; + int readSz = 20; + int actualCoreId; + + struct cpu_set_t cpuset; + CPU_ZERO(&cpuset);/* 初始化set集,将set置为空 */ + CPU_SET(1, &cpuset); /* cpu1 */ + printf("%s:[pid %d] sched_setaffinity(1) calling........\n", __FUNCTION__, getpid()); + ret = sched_setaffinity(getpid(), sizeof(struct cpu_set_t), &cpuset); + if (ret == -1) { + printf("Set CPU affinity failue, ERROR:%s\n", strerror(errno)); + return -1; + } + + + actualCoreId = showCpuAffinity(); + printf("%s:core=%d:[pid %d] confirm sched_getaffinity(0) result\n", __FUNCTION__, actualCoreId, getpid()); + + + char *uioIntDevname = "uio1"; + INTFd = openUioDevice(uioIntDevname); + printf("%s:core=%d:[pid %d] open INT Device %s, return fd=%d\n", __FUNCTION__, actualCoreId, getpid(), uioIntDevname, INTFd); + + // register 本侧中断处理 + printf("%s:core=%d:[pid %d] write to [register irq] turn on irq calling ........\n", __FUNCTION__, actualCoreId, getpid()); + const char outBuf[30] = "s123456789"; + int writeLen = write(INTFd, &outBuf[0], 10); + printf("%s:core=%d:[pid %d] write to [register irq] turn on irq ok, writeLen=%d\n", + __FUNCTION__, actualCoreId, getpid(), writeLen); + + + // mmap + // open uio1, + char *uioDataDevname = "uio0"; + dataFd = openUioDevice(uioDataDevname); + printf("%s:core=%d:[pid %d] open data Device %s, return fd=%d\n", __FUNCTION__, actualCoreId, getpid(), uioDataDevname, dataFd); + + printf("%s:core=%d:[pid %d] mmap (flag=%#x,PROT_READ)calling........\n", __FUNCTION__, actualCoreId, getpid(), PROT_READ); + src = mmap(0, mmapSize, PROT_READ, MAP_SHARED, dataFd, 0); + + // read data + printf("%s:core=%d:[pid %d]:calling read..............\n", __FUNCTION__, actualCoreId, getpid()); + char bufferRead[30] = {0}; + read(dataFd, bufferRead, readSz); + //memcpy(bufferRead, src, readSz); + + printf("%s:core=%d:[pid %d]:i read via SHARE_MEMORY result as [%s],readSz=%d\n", __FUNCTION__, actualCoreId, getpid(), bufferRead,readSz); + +#if 0 + // write data 写入数据为(ACK) + + // 通知另一侧读取 ioctl + int cmd = cmd_notify_start_read; + int flag = 0; + ioctl(fd, cmd, flag); +#endif + return 0; +} + +int appTwoProcess(void) +{ + int childPid; + childPid = fork(); + if (childPid == 0) { + printf("child %d start now, wait for input 1~9..............\n", getpid()); + waitInput(); + printf("\n\n.............child %d secondaryCoreProcess will run.........\n\n\n", getpid()); + secondaryCoreProcess(); + sleep(300); + + shutdownsecondaryProcess(); + + return 0; + } else { + printf("caller %d start now\n", getpid()); + mainCoreProcess(); + sleep(300); + + shutdownMainProcess(); + + return 0; + } + +} + +int waitInput(void) +{ + char *p; + int n; + + printf("Wait for input....\n"); + errno = 0; + n = scanf("%m[a-z]", &p); + if (n == 1) { + printf("read: %s\n", p); + free(p); + } else if (errno != 0) { + perror("scanf"); + } else { + fprintf(stderr, "No matching characters\n"); + } + return 0; +} + +int main(int argc, char *argv[]) +{ + appTwoProcess(); + + + printf("usage:\n"); + printf(" %s for uio1\n", argv[0]); + printf(" %s 1 for uio0\n", argv[0]); + printf(" %s 1 2 for old style\n", argv[0]); + if (argc == 1) { + mmapSendMsg("uio1"); + mmapEcho("uio1"); + } else if (argc == 2) { + mmapSendMsg("uio0"); + mmapEcho("uio0"); + } else { + accessMethod1(argc, argv); + } + + printf("[user]done\n"); + return 0; +} + + diff --git a/kernel/Kconfig b/kernel/Kconfig index bfd76c4c416e8bb41874eba1b401766552872131..7034bca38b1c0ffd48808058fa8b19eff93bb613 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1,4 +1,5 @@ menu "Kernel" + config KERNEL_SMP bool "Enable Kernel SMP" default n @@ -40,6 +41,31 @@ config KERNEL_SCHED_STATISTICS help This option will enable scheduler statistics. +config KERNEL_AMP + bool "Enable Kernel AMP" + default n + help + This option will enable amp support of LiteOS. + +choice + prompt "Choose AMP Core Mode" + depends on KERNEL_AMP + +config KERNEL_PRIMARY_CORE + bool "Enable Kernel Primary Core" + default n + depends on KERNEL_AMP + help + This option will enable primary core support of LiteOS. + +config KERNEL_SECONDARY_CORE + bool "Enable Kernel Secondary Core" + default n + depends on KERNEL_AMP + help + This option will enable secondary core support of LiteOS. +endchoice + config KERNEL_MMU bool "Enable MMU" default y diff --git a/kernel/base/include/los_vm_filemap.h b/kernel/base/include/los_vm_filemap.h index 7784cb56cdc8d3d8a9bfc30e7b98552e60f0ab56..b1e4d6a8618503333ee5bfddd05095d970095c08 100644 --- a/kernel/base/include/los_vm_filemap.h +++ b/kernel/base/include/los_vm_filemap.h @@ -188,6 +188,7 @@ typedef struct ProcessCB LosProcessCB; #ifdef LOSCFG_FS_VFS INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region); STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region); +STATUS_T OsUioMMap(struct file *filep, LosVmMapRegion *region); VOID OsVmmFileRegionFree(struct file *filep, LosProcessCB *processCB); #endif diff --git a/kernel/base/mp/los_spinlock.c b/kernel/base/mp/los_spinlock.c index 63d7fb500c96b93ad5dbee168e159fa5f7c136cc..2e0cdc123b9afd68f6d57c5830a1e6c79836ad5c 100644 --- a/kernel/base/mp/los_spinlock.c +++ b/kernel/base/mp/los_spinlock.c @@ -116,5 +116,61 @@ VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave) LOS_Schedule(); } } + +VOID LOS_SpinUnlockNoSchedRestore(SPIN_LOCK_S *lock, UINT32 intSave) +{ + LOCKDEP_CHECK_OUT(lock); + ArchSpinUnlock(&lock->rawLock); + + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + if (needSched) { + //LOS_Schedule(); + } +} +#else + +/* + * For Non-SMP system, these apis does not handle with spinlocks, + * but for unifying the code of drivers, vendors and etc. + */ +VOID LOS_SpinLock(SPIN_LOCK_S *lock) +{ + (VOID)lock; +} + +INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock) +{ + (VOID)lock; + return LOS_OK; +} + +VOID LOS_SpinUnlock(SPIN_LOCK_S *lock) +{ + (VOID)lock; +} + +VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave) +{ + (VOID)lock; + *intSave = LOS_IntLock(); +} + +VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave) +{ + (VOID)lock; + LOS_IntRestore(intSave); +} + +BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock) +{ + (VOID)lock; + return TRUE; +} + +VOID LOS_SpinInit(SPIN_LOCK_S *lock) +{ + (VOID)lock; +} #endif diff --git a/kernel/base/vm/los_vm_filemap.c b/kernel/base/vm/los_vm_filemap.c index 9d34aeec0709ad91cc5e683aff7c070dc3b2eb48..cfc60f69207766044fab55633357ebe2d83ae2d5 100644 --- a/kernel/base/vm/los_vm_filemap.c +++ b/kernel/base/vm/los_vm_filemap.c @@ -538,6 +538,38 @@ STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region) return LOS_OK; } + +STATUS_T OsUioMMap(struct file *filep, LosVmMapRegion *region) +{ + struct Vnode *vnode = NULL; + if (filep == NULL) { + return LOS_ERRNO_VM_MAP_FAILED; + } + file_hold(filep); + vnode = filep->f_vnode; + VnodeHold(); + vnode->useCount++; + VnodeDrop(); + if (filep->ops != NULL && filep->ops->mmap != NULL) { + if (vnode->type == VNODE_TYPE_CHR || vnode->type == VNODE_TYPE_BLK) { + LOS_SetRegionTypeDev(region); + } else { + LOS_SetRegionTypeFile(region); + } + int ret = filep->ops->mmap(filep, region); + if (ret != LOS_OK) { + file_release(filep); + return LOS_ERRNO_VM_MAP_FAILED; + } + } else { + VM_ERR("mmap file type unknown"); + file_release(filep); + return LOS_ERRNO_VM_MAP_FAILED; + } + file_release(filep); + return LOS_OK; +} + LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff) { LosFilePage *fpage = NULL; diff --git a/kernel/base/vm/los_vm_syscall.c b/kernel/base/vm/los_vm_syscall.c index 1f6d600e8547fca6284f3c284bf7d2cd7d63e361..aedf20116cada30d44a26445f1f9a57e09394b39 100644 --- a/kernel/base/vm/los_vm_syscall.c +++ b/kernel/base/vm/los_vm_syscall.c @@ -102,8 +102,27 @@ STATUS_T OsAnonMMap(LosVmMapRegion *region) return LOS_OK; } +extern int LOS_IsUioOwnMmapType(struct file *filep); +VADDR_T LOS_NewMMap(struct file *filep, size_t len) +{ + VADDR_T resultVaddr; + LosVmMapRegion *newRegion = NULL; +// newRegion = LOS_RegionAlloc(vmSpace, vaddr, len, regionFlags, pgoff);//create by phy --------------- +// resultVaddr = newRegion->range.base;//---------------------- + + if (filep->ops != NULL && filep->ops->mmap != NULL) { + + int ret = filep->ops->mmap(filep, newRegion); + PRINT_ERR("[kernel]LOS_NewMMap:call ops->mmap ret=%d\n", ret); + } + resultVaddr = newRegion->range.base;//---------------------- + PRINT_ERR("[kernel]LOS_NewMMap:call ops->mmap create resultVaddr=%#x\n", resultVaddr); + return resultVaddr;//--------------------------- +} + VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, int fd, unsigned long pgoff) { + STATUS_T status; VADDR_T resultVaddr; UINT32 regionFlags; @@ -129,7 +148,14 @@ VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, } } + (VOID)LOS_MuxAcquire(&vmSpace->regionMux); + + + //PRINT_ERR("===========================xzg kernel=========================\n\n"); + //PRINT_ERR("[kernel]LOS_MMap:use orginal mmap still\n\n"); + + /* user mode calls mmap to release heap physical memory without releasing heap virtual space */ status = OsUserHeapFree(vmSpace, vaddr, len); if (status == LOS_OK) { @@ -138,13 +164,13 @@ VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, } regionFlags = OsCvtProtFlagsToRegionFlags(prot, flags); - newRegion = LOS_RegionAlloc(vmSpace, vaddr, len, regionFlags, pgoff); + newRegion = LOS_RegionAlloc(vmSpace, vaddr, len, regionFlags, pgoff);//create--------------- if (newRegion == NULL) { resultVaddr = (VADDR_T)-ENOMEM; goto MMAP_DONE; } newRegion->regionFlags |= VM_MAP_REGION_FLAG_MMAP; - resultVaddr = newRegion->range.base; + resultVaddr = newRegion->range.base;//---------------------- if (LOS_IsNamedMapping(flags)) { status = OsNamedMMap(filep, newRegion); @@ -161,7 +187,7 @@ VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, MMAP_DONE: (VOID)LOS_MuxRelease(&vmSpace->regionMux); - return resultVaddr; + return resultVaddr;//--------------------------- } STATUS_T LOS_UnMMap(VADDR_T addr, size_t size) diff --git a/kernel/common/BUILD.gn b/kernel/common/BUILD.gn index 476ab6d717a4cbd2510df1f04876576204a62965..d59a0808ca3222e0d2de69d8ad7fba69fabde5f5 100644 --- a/kernel/common/BUILD.gn +++ b/kernel/common/BUILD.gn @@ -37,6 +37,7 @@ kernel_module(module_name) { "los_init.c", "los_magickey.c", "los_printf.c", + "los_uio.c", "main.c", ] diff --git a/kernel/common/los_config.c b/kernel/common/los_config.c index 0d1e397f9f72a25db5a72c3d2ae5bd6feb9d56ed..03c1e6a03dd50f503b2f3740774e853514d0c3fa 100644 --- a/kernel/common/los_config.c +++ b/kernel/common/los_config.c @@ -57,6 +57,10 @@ #include "los_smp.h" #include "los_container_bundle.h" + +extern int uio_register_0(void); +extern int uio_register_1(void); + STATIC SystemRebootFunc g_rebootHook = NULL; VOID OsSetRebootHook(SystemRebootFunc func) @@ -216,8 +220,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsMain(VOID) /* system and chip info */ OsSystemInfo(); - - PRINT_RELEASE("\nmain core booting up...\n"); + UINT32 cpuid = ArchCurrCpuid(); + PRINT_RELEASE("\n[primary core]cpu-%d,main core booting up...\n", cpuid); #ifdef LOS_INIT_STATISTICS startNsec = LOS_CurrNanosec(); @@ -284,9 +288,20 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsMain(VOID) #ifdef LOS_INIT_STATISTICS endNsec = LOS_CurrNanosec(); durationUsec = (endNsec - startNsec) / OS_SYS_NS_PER_US; - PRINTK("The main core takes %lluus to start.\n", durationUsec); + PRINTK("[primary core]The main core takes %lluus to start.\n", durationUsec); #endif +#if ((defined LOSCFG_KERNEL_PRIMARY_CORE) || (defined LOSCFG_KERNEL_SECONDARY_CORE)) + uio_register_0(); + uio_register_1(); + PRINT_ERR("[primary core][kernel]:uio_register_0/1 called\n"); +#endif + uio_register_0(); + uio_register_1(); + UINT32 cpuidDbg = ArchCurrCpuid(); + PRINT_ERR("[primary core][kernel]cpu-%d:uio_register_0/1 called\n", cpuidDbg); + + return LOS_OK; } diff --git a/kernel/common/los_uio.c b/kernel/common/los_uio.c new file mode 100644 index 0000000000000000000000000000000000000000..db466650c2be4e954da2f9cef1f4b3ebff5c72fe --- /dev/null +++ b/kernel/common/los_uio.c @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ +#include "los_config.h" +#include "los_process_pri.h" +#include "los_arch_mmu.h" +#include "fs/file.h" +#include "fs/driver.h" +#include "los_vm_map.h" +#include "los_task.h" +#include "los_uio.h" + + +#define UIO_MEM_BASE_ADDR DDR_MEM_AMP_SHM_ADDR + +#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) +#define MODULE_NAME_LEN MAX_PARAM_PREFIX_LEN + + +#define USE_COMMON_MMAP (0) +#define USE_OWN_MMAP (1) + + +#define LOS_MP_IPI_NOTIFY 15 + + +#define MAGIC "070707" + +typedef struct { + UINT32 magicNum; + UINT32 uioDevID; + UINT32 uioDevType; + CHAR *uioName; + INT32 fd; + UINT32 readShmSem; +} UIO_DEV_CB; + + + +const UINT32 g_mpShareMemroySize = 2 * 1024 * 1024; +const PADDR_T g_mpShareMemroyBase = 0x88000000 - g_mpShareMemroySize; +PADDR_T g_mpShareMemroyAllocBase; +UINT32 g_readShmSem; + + +STATIC UIO_DEV_CB *UioDevGetAttr(struct file *filep); +STATIC INT32 UioDevSetAttr(struct file *filep); + + +int LOS_IsUioOwnMmapType(struct file *filep) +{ + UIO_DEV_CB *uioCbGet = NULL; + if (filep == NULL) + { + PRINT_ERR("[kernel]LOS_IsUioOwnMmapType:error, filep is NULL\n"); + return FALSE; + } + uioCbGet = UioDevGetAttr(filep); + PRINT_ERR("[kernel]LOS_IsUioOwnMmapType:path=%s, val magic=%#x, id=%#x,[type=%#x],name=%s\n", + filep->f_path, uioCbGet->magicNum, uioCbGet->uioDevID, uioCbGet->uioDevType, uioCbGet->uioName); + + if (uioCbGet->uioDevType == USE_OWN_MMAP) + { + PRINT_ERR("[kernel]LOS_IsUioOwnMmapType:yes, found is Own MMap for you\n"); + return TRUE; + } else { + return FALSE; + } +} + + +STATIC UIO_DEV_CB * UioDevGetAttr(struct file *filep) +{ + UIO_DEV_CB *uioCbOut = (UIO_DEV_CB *)filep->f_priv; + + return uioCbOut; +} + +STATIC INT32 UioDevSetAttr(struct file *filep) +{ + UINT32 cpuId = ArchCurrCpuid(); + UINT32 processId = LOS_GetCurrProcessID(); + + UIO_DEV_CB *uioCb = NULL; + uioCb = (UIO_DEV_CB *)filep->f_priv; + if (uioCb == NULL) { + return -EFAULT; + } + PRINT_ERR("[kernle]%s:cpu=%d,pid=%d:enter now, next create sem.......\n", __FUNCTION__, cpuId, processId); + if (LOS_BinarySemCreate(0, &g_readShmSem) != LOS_OK) { + return LOS_NOK; + } + + uioCb->uioName = "uio1"; + uioCb->uioDevType = USE_OWN_MMAP; + + PRINT_ERR("[kernel]%s:cpu=%d,pid=%d:set ok, path=%s, val magic=%#x, id=%#x,[type=%#x],name=%s\n", + __FUNCTION__, cpuId, processId, filep->f_path, uioCb->magicNum, uioCb->uioDevID, uioCb->uioDevType, uioCb->uioName); + return LOS_OK; +} + +static UINT32 allocPhyMemForRegion(LosVmMapRegion *region) +{ + UINT32 cpuId = ArchCurrCpuid(); + UINT32 processId = LOS_GetCurrProcessID(); + UINT32 shm_size = 2 * 1024 * 1024; + UINT32 numPages; + PADDR_T paddr = 0x88000000 - shm_size; + VADDR_T vaddr; + //LosVmMapRegion *region = NULL; + LosVmPage *page = NULL; + LosProcessCB *runProcessCB = OsCurrProcessGet(); + LosVmSpace *space = runProcessCB->vmSpace; + UINT32 i; + status_t ret; + UINT32 regionFlags; + + + PRINT_ERR("[kernle]cpu=%d,pid=%d:allocVmspaceFromPhy enter,region info below:\n", cpuId, processId); + PRINT_ERR("[kernle]base=%#x, size=%#x, type=%#x(ANON=1,FILE=2,DEV=4), flag=%#x,shmid=%#x, offset=%#x,ra.node=%#x\n", + region->range.base, region->range.size, region->regionType, region->regionFlags, region->shmid, + region->pgOff, region->unTypeData.ra.node); + + + numPages = region->range.size >> PAGE_SHIFT;//计算线性区页数 + PRINT_ERR("[kernle]allocVmspaceFromPhy:check rang.size=%d(expect:2MB), numPages=%d\n", region->range.size, numPages); + + paddr = 0x88000000 - shm_size; + regionFlags = region->regionFlags; + for (i = 0; i < numPages; i++) {//一页一页进行重新映射 + // step 2:just alloc paddr by ourself, as 0x88000000 - shm_size; + // todo..... + vaddr = region->range.base + (i << PAGE_SHIFT); + paddr += i << PAGE_SHIFT; + + PRINT_ERR("[kernle]allocVmspaceFromPhy:ArchMmuMap(turn #%d):set vaddr=%#x,paddr=%#x, on base================================\n", + i, vaddr, paddr); + + + // todo: 被人重复映射,会竞争写入同一块物理内存。待加锁。 + + ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, NULL, NULL);//查询是否缺页 + if (ret == LOS_OK) { + PRINT_ERR("[kernle]allocVmspaceFromPhy:query:found NOT need phy page\n"); + } else { + PRINT_ERR("[kernle]allocVmspaceFromPhy:query:found need phy page\n"); + } + +#if 0 // step 1:just get paddr by system + if (LOS_ArchMmuQuery(&space->archMmu, vaddr, &paddr, ®ionFlags) != LOS_OK) {//先查物理地址 + PRINT_ERR("[kernle]allocVmspaceFromPhy:error, LOS_ArchMmuQuery return error\n"); +// continue; + } +#endif + + page = LOS_VmPageGet(paddr);//通过物理页获取物理内存的页框 + if (page != NULL) { + LOS_AtomicInc(&page->refCounts);//refCounts 自增 + }else{ + PRINT_ERR("[kernle]allocVmspaceFromPhy:Error. LOS_VmPageGet get page is NULL\n"); + return LOS_NOK; + } + PRINT_ERR("[kernle]allocVmspaceFromPhy:get page from paddr(%#x), page:phyAddr=%#x, ref=%d,flag=%#x,segId=%d,npages=%d\n", + paddr,page->physAddr, page->refCounts, page->flags, page->segID, page->nPages); + + //LOS_ArchMmuUnmap(&space->archMmu, vaddr, 1);//先删除已有空间映射 + STATUS_T err = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, regionFlags);//映射新空间 + if (err < 0) { + PRINT_ERR("%s, %d Error.LOS_ArchMmuMap return error\n", __FUNCTION__, __LINE__); + return LOS_NOK; + } + + // todo: 需要记录,被申请掉的物理内存到哪里了,往前推进。 + g_mpShareMemroyAllocBase = paddr + (1 << PAGE_SHIFT); + PRINT_ERR("[kernle]allocVmspaceFromPhy:ArchMmuMap(turn #%d):OK, for vaddr=%p, paddr=%p,g_alloc reach to %#x\n\n", + i, vaddr, paddr,g_mpShareMemroyAllocBase); + } + return LOS_OK; +} + +static int uio_mmap(struct file* filep, struct VmMapRegion *region) +{ + UINT32 cpuId = ArchCurrCpuid(); + UINT32 processId = LOS_GetCurrProcessID(); + + PRINT_ERR("[kernle]%s:cpu=%d,pid=%d:enter now\n", __FUNCTION__, cpuId, processId); + + int ret = allocPhyMemForRegion(region); + + return ret; +} + +static ssize_t uio_read(struct file *filep, char *buffer, size_t buflen) +{ + UINT32 cpuId = ArchCurrCpuid(); + UINT32 processId = LOS_GetCurrProcessID(); + UIO_DEV_CB *uioCb = NULL; + uioCb = (UIO_DEV_CB *)filep->f_priv; + + PRINT_ERR("[kernel]uio_read:cpu-[%d]cpu=%d,pid=%d:enter now, copy bufferToUser, semPending now..........\n", cpuId, processId); + PRINT_ERR("[kernel]uio_read:filep info:path=%s,dir=%s,oflags=%#x(expect:02),pos=%d,ref=%lu,fd=%d\n", + filep->f_path, filep->f_dir, filep->f_oflags, + filep->f_pos, filep->f_refcount, filep->fd); + + if (LOS_SemPend(g_readShmSem, LOS_WAIT_FOREVER) != LOS_OK) { + goto ERROR_UIO; + } + + if (LOS_IsUserAddressRange((vaddr_t)(uintptr_t)buffer, buflen)) { + + // 维护共享内存的 头尾指针------算法。 todo + // add code here........................ + + char bufOut[30] = "abcabcabcabc"; + memcpy_s(buffer, buflen, bufOut, buflen); + PRINT_ERR("[kernel]:uio_read call, bufferToUser = [%s], len=%d\n", bufOut, buflen); + return buflen; + + } else { + + PRINT_ERR("[kernel]:uio_read call, user buffer is invalid\n"); + return -1; + } + +ERROR_UIO: + return -1; + +} + + +STATIC VOID IsrHandleNotify(VOID) +{ + UINT32 cpuId = ArchCurrCpuid(); + UINT32 processId = LOS_GetCurrProcessID(); + PRINT_ERR("[kernle]%s:cpu=%d,pid=%d:ISR enter now, now post the sem...........\n", __FUNCTION__, cpuId, processId); + + // 收到中断后,让本侧继续读取。Linux 等待队列 + if (LOS_SemPost(g_readShmSem) != LOS_OK) + { + PRINT_ERR("[kernel]IsrHandleNotify:cpu=%d,pid=%d, failed to post g_readShmSem\n", cpuId, processId); + return; + } + + PRINT_ERR("[kernel]IsrHandleNotify:cpu=%d,pid=%d: post g_readShmSem ok\n", cpuId, processId); +} + + +static int NotifyRemoteProcess(unsigned long arg) +{ + (void)arg; + UINT32 cpuId = ArchCurrCpuid(); + UINT32 processId = LOS_GetCurrProcessID(); + UINT32 target = (UINT32)(OS_MP_CPU_ALL & ~CPUID_TO_AFFI_MASK(cpuId)); + + + PRINT_ERR("[kernle]%s,cpu=%d,pid=%d:next sendIPI to target %d(cpu-%d), event=%#x......\n", + __FUNCTION__, cpuId, processId, target, cpuId, LOS_MP_IPI_NOTIFY); + HalIrqSendIpi(target, LOS_MP_IPI_NOTIFY); + PRINT_ERR("[kernle]%s:cpu=%d,pid=%d: sendIPI ok\n", __FUNCTION__, cpuId, processId); + return 0; +} + + + +static ssize_t uio_write0(struct file *filep, const char *buffer, size_t len) +{ + UINT32 cpuId = ArchCurrCpuid(); + UINT32 processId = LOS_GetCurrProcessID(); + PRINT_ERR("[kernle]%s:cpu=%d,pid=%d:enter now, do nothing\n", __FUNCTION__, cpuId, processId); + return -1; +} + + +static ssize_t uio_write1(struct file *filep, const char *buffer, size_t len) +{ + UINT32 cpuId = ArchCurrCpuid(); + UINT32 processId = LOS_GetCurrProcessID(); + PRINT_ERR("[kernle]%s:cpu=%d,pid=%d:enter now, register the handler for vector %d (LOS_MP_IPI_NOTIFY)\n", + __FUNCTION__, cpuId, processId, LOS_MP_IPI_NOTIFY); + //int irqOn = *(int*)buffer; + // write REG. enable 本侧的中断处理函数. + (VOID)LOS_HwiCreate(LOS_MP_IPI_NOTIFY, 0xa0, 0, IsrHandleNotify, 0); + PRINT_ERR("[kernle]%s:cpu=%d,pid=%d: register ISR ok\n", __FUNCTION__, cpuId, processId); + + return len; +} + + + + +static int uio_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + UINT32 cpuId = ArchCurrCpuid(); + UINT32 processId = LOS_GetCurrProcessID(); + PRINT_ERR("[kernel]uio_ioctl:cpu=%d,pid=%d:enter\n", cpuId, processId); + + switch (cmd) { + case cmd_notify_start_read: { + + NotifyRemoteProcess(arg); + break; + + } + default: + break; + } + + return 3; + +} + + +STATIC INT32 uio_open(struct file *filep) +{ + UINT32 cpuId = ArchCurrCpuid(); + UINT32 processId = LOS_GetCurrProcessID(); + PRINT_ERR("[kernel]uio_open:cpu=%d,pid=%d:cpu-%d, do nothing actually\n", cpuId, processId, filep->f_path); + PRINT_ERR("[kernel]uio_open:filep info:path=%s,dir=%s,oflags=%#x(expect:02),pos=%d,ref=%lu,fd=%d\n", + filep->f_path, filep->f_dir, filep->f_oflags, + filep->f_pos, filep->f_refcount, filep->fd); + + UioDevSetAttr(filep); + LOS_IsUioOwnMmapType(filep); + + return 0; + +} + + +const struct file_operations_vfs uio_fops0 = +{ + .open = uio_open, /* open */ + .close = NULL, /* close */ + .read = uio_read, /* read */ + .write = uio_write0, /* write */ + .seek = NULL, /* seek */ + .ioctl = NULL, /* ioctl */ + .unlink = NULL, /* unlink */ + .mmap = uio_mmap, +}; + +const struct file_operations_vfs uio_fops1 = +{ + .open = uio_open, /* open */ + .close = NULL, /* close */ + .read = uio_read, /* read */ + .write = uio_write1, /* write */ + .seek = NULL, /* seek */ + .ioctl = uio_ioctl, /* ioctl */ + .unlink = NULL, /* unlink */ + .mmap = uio_mmap, +}; + +int uio_register_0(void) +{ +//chenzhan:UIO0-INT +//chenzhan:UIO1-DATA-mmap + + int ret; + char *uiodev = "/dev/uio0";// share memory + ret = register_driver(uiodev, &uio_fops0, 0777, NULL); + + PRINT_ERR("[kernel]uio_register_0:register_driver /dev/uio0 ret=%d\n", ret); + + return ret; +} + +int uio_register_1(void) +{ +//chenzhan:UIO0-INT +//chenzhan:UIO1-DATA-mmap + + int ret; + char *uiodev = "/dev/uio1"; // ipi + ret = register_driver(uiodev, &uio_fops1, 0777, NULL); + PRINT_ERR("[kernel]uio_register_1:register_driver /dev/uio1 ret=%d\n", ret); + + return ret; +} + + + diff --git a/kernel/common/main.c b/kernel/common/main.c index 66f9e9860701fd2972ccc42a7bda61f8e51bead2..7e0a10e1e0984ba153f616392c11f940efde9b4d 100644 --- a/kernel/common/main.c +++ b/kernel/common/main.c @@ -32,6 +32,58 @@ #include "los_config.h" #include "los_sched_pri.h" +#define NUM_1 1 +#define NUM_2 2 +#define __arch_getl(a) (*(volatile unsigned int *)(a)) +#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) +#define dmb() DMB +#define __iormb() dmb() +#define __iowmb() dmb() + + +#define readl(c) ({ UINT32 __v = __arch_getl(c); __iormb(); __v; }) +#define writel(v,c) ({ UINT32 __v = v; __iowmb(); __arch_putl(__v,c); __v; }) + +#define BOOTROM_PHYS_BASE 0 +#define BOOTROM_VIRT_BASE (PERIPH_UNCACHED_BASE + PERIPH_UNCACHED_SIZE) + +#define CLEAR_RESET_REG_STATUS(regval) (regval) &= ~(1U << 2) + +void flush_dcache_all(void) +{ + + DCacheInvRange(BOOTROM_VIRT_BASE, BOOTROM_VIRT_BASE + 8); + +} + +int start_other_cpus(void) +{ + /* prepare two commands for cortex-a17 */ + volatile int cmd_address = 0; + volatile int cmd = 0xe51ff004; /* 0xe51ff004:Default liteos address. */ + unsigned int regval; + + UINT32 cpuid = ArchCurrCpuid(); + + PRINT_ERR("[kernel]start_other_cpus-cpu %d:start\n\n\n", cpuid); + + + flush_dcache_all(); + asm("str %0, [%1]"::"r"(cmd), "r"(cmd_address): "cc"); + cmd = 0x85c00000; /* 16:base */ + PRINT_ERR("starting cpu1 liteos address 0x%x\n", cmd); + asm("str %0, [%1, #4]"::"r"(cmd), "r"(cmd_address): "cc"); + /* clear the slave cpu reset */ + /* 0x12010000:CRG base address; 0x0078:PERI_CRG30 */ + regval = readl(0x12010000 + 0x0078); + regval &= ~(NUM_1 << NUM_2); + /* 0x12010000:CRG base address; 0x0078:PERI_CRG30 */ + writel(regval, (0x12010000 + 0x0078)); + PRINT_ERR("[kernel]start_other_cpus-cpu %d:exit\n\n\n", cpuid); + return 0; +} + + LITE_OS_SEC_TEXT_INIT INT32 main(VOID) { UINT32 ret = OsMain(); @@ -40,7 +92,16 @@ LITE_OS_SEC_TEXT_INIT INT32 main(VOID) } CPU_MAP_SET(0, OsHwIDGet()); +#if ((defined LOSCFG_KERNEL_PRIMARY_CORE) || (defined LOSCFG_KERNEL_SECONDARY_CORE)) +//#error "define openAMP" + SEV; + (void)start_other_cpus(); +#endif + + UINT32 cpuid = ArchCurrCpuid(); + PRINT_ERR("[kernel]main:OsSchedStart-cpu %d:start\n", cpuid); OsSchedStart(); + PRINT_ERR("[kernel]main:OsSchedStart-cpu %d:done\n", cpuid); while (1) { __asm volatile("wfi"); diff --git a/kernel/include/los_mp.h b/kernel/include/los_mp.h index 67bbd39c7bb532de74d087d39fa6d52e1f42872d..8833b1f14f622089c06c0073387f7c4c02ab96aa 100644 --- a/kernel/include/los_mp.h +++ b/kernel/include/los_mp.h @@ -52,6 +52,7 @@ typedef enum { #ifdef LOSCFG_KERNEL_SMP_CALL LOS_MP_IPI_FUNC_CALL, #endif + LOS_MP_IPI_WRITE, } MP_IPI_TYPE; typedef VOID (*SMP_FUNC_CALL)(VOID *args); diff --git a/kernel/include/los_spinlock.h b/kernel/include/los_spinlock.h index 8ee14b9d2201a82f3deb88ef99ddf8fa34f7dad6..ab386f020280621e1dc736262884fef8586e74a0 100644 --- a/kernel/include/los_spinlock.h +++ b/kernel/include/los_spinlock.h @@ -218,45 +218,51 @@ extern VOID LOS_SpinInit(SPIN_LOCK_S *lock); * For Non-SMP system, these apis does not handle with spinlocks, * but for unifying the code of drivers, vendors and etc. */ -LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLock(SPIN_LOCK_S *lock) -{ - (VOID)lock; -} - -LITE_OS_SEC_ALW_INLINE STATIC INLINE INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock) -{ - (VOID)lock; - return LOS_OK; -} +// LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLock(SPIN_LOCK_S *lock) +// { +// (VOID)lock; +// } -LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlock(SPIN_LOCK_S *lock) -{ - (VOID)lock; -} +// LITE_OS_SEC_ALW_INLINE STATIC INLINE INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock) +// { +// (VOID)lock; +// return LOS_OK; +// } -LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave) -{ - (VOID)lock; - *intSave = LOS_IntLock(); -} +// LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlock(SPIN_LOCK_S *lock) +// { +// (VOID)lock; +// } -LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave) -{ - (VOID)lock; - LOS_IntRestore(intSave); -} +// LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave) +// { +// (VOID)lock; +// *intSave = LOS_IntLock(); +// } -LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock) -{ - (VOID)lock; - return TRUE; -} +// LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave) +// { +// (VOID)lock; +// LOS_IntRestore(intSave); +// } -LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinInit(SPIN_LOCK_S *lock) -{ - (VOID)lock; -} +// LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock) +// { +// (VOID)lock; +// return TRUE; +// } +// LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinInit(SPIN_LOCK_S *lock) +// { +// (VOID)lock; +// } +VOID LOS_SpinLock(SPIN_LOCK_S *lock); +INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock); +VOID LOS_SpinUnlock(SPIN_LOCK_S *lock); +VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave); +VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave); +BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock); +VOID LOS_SpinInit(SPIN_LOCK_S *lock); #endif #define SPIN_LOCK_INIT(lock) SPIN_LOCK_S lock = SPIN_LOCK_INITIALIZER(lock) diff --git a/kernel/include/los_uio.h b/kernel/include/los_uio.h new file mode 100644 index 0000000000000000000000000000000000000000..965fc5a38765e09195db24c700c45624c0b3d59f --- /dev/null +++ b/kernel/include/los_uio.h @@ -0,0 +1,8 @@ + + + + +#define cmd_notify_start_read 1 +#define cmd_notify_shutdown 2 +#define cmd_notify_wakeup 3 +