diff --git a/library/include/mica/mica.h b/library/include/mica/mica.h index 0429adf2ecd911a0b32c98f219109eee50901005..480f5a0d826f84fba1c4a244b7e93a08e4643062 100644 --- a/library/include/mica/mica.h +++ b/library/include/mica/mica.h @@ -21,11 +21,16 @@ extern "C" { int mica_create(struct mica_client *client); int mica_start(struct mica_client *client); +void mica_stop(struct mica_client *client); +// TODO: delete client const char *mica_status(struct mica_client *client); /* register a rpmsg/user-defined service */ int mica_register_service(struct mica_client *client, struct mica_service *svc); +/* unregister all the registered services */ +void mica_unregister_all_services(struct mica_client *client); + void mica_print_service(struct mica_client *client, char *str, size_t size); void print_device_of_service(struct mica_client *client, char *str, size_t size); diff --git a/library/include/mica/mica_client.h b/library/include/mica/mica_client.h index 0e597992fbaefa65cd5d7b20743d39016c99ec78..e140d2cd56a40472989a99bfc4e2df9fc42ed7ff 100644 --- a/library/include/mica/mica_client.h +++ b/library/include/mica/mica_client.h @@ -28,13 +28,11 @@ enum rproc_mode { RPROC_MODE_BARE_METAL = 0, }; +extern struct metal_list g_client_list; + struct mica_client { const struct rpmsg_virtio_config *config; - /* The static memory is deprecated and will be removed soon */ - metal_phys_addr_t static_mem_base; - unsigned int static_mem_size; - /* client os firmware path */ char path[MAX_FIRMWARE_PATH_LEN]; /* the target CPU */ @@ -58,11 +56,11 @@ struct mica_client { struct rpmsg_virtio_shm_pool vdev_shpool; /* rpmsg device */ struct rpmsg_device *rdev; - /* notification waiter */ - int (*wait_event)(void); /* the bound services */ struct metal_list services; + /* the client list */ + struct metal_list node; }; /** @@ -84,8 +82,8 @@ struct mica_service { void *priv; /*For user-defined service */ - int (*init) (void *priv); - void (*remove) (void *priv); + int (*init) (struct mica_service *svc); + void (*remove) (struct mica_service *svc); /*For rpmsg service */ bool (*rpmsg_ns_match) (struct rpmsg_device *rdev, diff --git a/library/include/remoteproc/remoteproc_module.h b/library/include/remoteproc/remoteproc_module.h index c8bb69dc9e50503c0538111da09f9ec8d168caa7..dc2d230a0f1c3d57868bc7edd11bbd014f1da4c2 100644 --- a/library/include/remoteproc/remoteproc_module.h +++ b/library/include/remoteproc/remoteproc_module.h @@ -13,10 +13,6 @@ extern "C" { #endif -#define CPU_STATE_ON 0 -#define CPU_STATE_OFF 1 -#define CPU_STATE_ON_PENDING 2 - struct img_store { FILE *file; @@ -27,6 +23,7 @@ struct img_store int create_client(struct mica_client *client); int load_client_image(struct mica_client *client); int start_client(struct mica_client *client); +void stop_client(struct mica_client *client); /* destory remoteproc */ void destory_client(struct mica_client *client); diff --git a/library/include/rpmsg/rpmsg_vdev.h b/library/include/rpmsg/rpmsg_vdev.h index 7adf878a23439a542eba8658e003d8796f1a763d..49bbc38c816ffbb442a2383c01bcd6a083622ed0 100644 --- a/library/include/rpmsg/rpmsg_vdev.h +++ b/library/include/rpmsg/rpmsg_vdev.h @@ -14,6 +14,7 @@ extern "C" { #endif int create_rpmsg_device(struct mica_client *client); +void release_rpmsg_device(struct mica_client *client); #if defined __cplusplus } diff --git a/library/memory/shm_pool.c b/library/memory/shm_pool.c index fb994584dd61333165305b11f7d7b4f0e12c6b77..20aeb106336863df500d464e64824f910a549172 100644 --- a/library/memory/shm_pool.c +++ b/library/memory/shm_pool.c @@ -29,12 +29,6 @@ int init_shmem_pool(struct mica_client *client, metal_phys_addr_t pa, size_t siz { void *va; - if (client->phys_shmem_start != 0) { - syslog(LOG_ERR, "%s failed: the shared memory of this client has been registered\n", - __func__); - return -EPERM; - } - va = remoteproc_mmap(&client->rproc, &pa, NULL, size, 0, &client->shbuf_io); if (!va) return -EPERM; diff --git a/library/mica/mica.c b/library/mica/mica.c index 26043ceb144fbef11d6658253c0ecd706ab3a406..1c14b4638aaec27c0f5d416c23847edf7de2ba5a 100644 --- a/library/mica/mica.c +++ b/library/mica/mica.c @@ -16,16 +16,8 @@ int mica_create(struct mica_client *client) int ret; ret = create_client(client); - if (ret) { + if (ret) syslog(LOG_ERR, "create remoteproc failed, err: %d\n", ret); - return ret; - } - - ret = load_client_image(client); - if (ret) { - syslog(LOG_ERR, "load client image failed, err: %d\n", ret); - return ret; - } return ret; } @@ -34,10 +26,17 @@ int mica_start(struct mica_client *client) { int ret; + ret = load_client_image(client); + if (ret) { + syslog(LOG_ERR, "load client image failed, err: %d\n", ret); + return ret; + } + ret = start_client(client); - if (ret) + if (ret) { syslog(LOG_ERR, "start client OS failed, err: %d\n", ret); - /* TODO: free rpmsg device */ + return ret; + } ret = create_rpmsg_device(client); if (ret) @@ -46,6 +45,18 @@ int mica_start(struct mica_client *client) return ret; } +void mica_stop(struct mica_client *client) +{ + /* + * step1: remove all the registered services + * step2: remove rpmsg device + * step3: shutdown remoteproc + */ + mica_unregister_all_services(client); + release_rpmsg_device(client); + stop_client(client); +} + const char *mica_status(struct mica_client *client) { return show_client_status(client); diff --git a/library/remoteproc/baremetal_rproc.c b/library/remoteproc/baremetal_rproc.c index 39202ba4d169b8bacbb22ccb290594be897760f6..cc3db61d9a16492eb54ce40a24457330f7145e4d 100644 --- a/library/remoteproc/baremetal_rproc.c +++ b/library/remoteproc/baremetal_rproc.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -25,21 +26,51 @@ struct cpu_info { uint64_t boot_addr; }; +struct mem_info { + uint64_t phy_addr; + uint64_t size; +}; + static int mcs_fd; #define MCS_DEVICE_NAME "/dev/mcs" #define IOC_SENDIPI _IOW('A', 0, int) #define IOC_CPUON _IOW('A', 1, int) #define IOC_AFFINITY_INFO _IOW('A', 2, int) +#define IOC_QUERY_MEM _IOW('A', 3, int) /* PSCI FUNCTIONS */ #define CPU_ON_FUNCID 0xC4000003 +#define CPU_OFF_FUNCID 0x84000002 #define SYSTEM_RESET 0x84000009 + +/* shared memory pool size: 128 K */ +#define SHM_POOL_SIZE 0x20000 + +static atomic_bool notifier = false; +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +static void rproc_notify_all(void) +{ + int find = 0; + struct metal_list *node; + struct mica_client *client; + + metal_list_for_each(&g_client_list, node) { + client = metal_container_of(node, struct mica_client, node); + if (client->mode == RPROC_MODE_BARE_METAL) { + find = 1; + remoteproc_get_notification(&client->rproc, 0); + } + } + + notifier = find ? true : false; +} + /* * Listen to events sent from the remote - * - * @returns: Returns a non-negative value when an event arrives, -1 on error. */ -static int rproc_wait_event(void) +static void *rproc_wait_event(void *arg) { int ret; struct pollfd fds = { @@ -47,7 +78,12 @@ static int rproc_wait_event(void) .events = POLLIN }; - while (1) { + notifier = true; + pthread_mutex_lock(&mutex); + pthread_cond_broadcast(&cond); + pthread_mutex_unlock(&mutex); + + while (notifier) { ret = poll(&fds, 1, -1); if (ret == -1) { syslog(LOG_ERR, "%s failed: %s\n", __func__, strerror(errno)); @@ -55,9 +91,36 @@ static int rproc_wait_event(void) } if (fds.revents & POLLIN) - break; + rproc_notify_all(); } + pthread_exit(NULL); +} + +static int rproc_register_notifier() +{ + int ret = 0; + pthread_t thread; + + /* + * In bare-metal mode, we only need to register one notifier. + */ + if (notifier) + return ret; + + ret = pthread_create(&thread, NULL, rproc_wait_event, NULL); + if (ret) + return ret; + + ret = pthread_detach(thread); + if (ret) + pthread_cancel(thread); + + pthread_mutex_lock(&mutex); + pthread_cond_wait(&cond, &mutex); + pthread_mutex_unlock(&mutex); + + ret = notifier ? 0 : -1; return ret; } @@ -81,26 +144,16 @@ static struct remoteproc *rproc_init(struct remoteproc *rproc, } /* set up the notification waiter */ - client->wait_event = rproc_wait_event; - - /* - * Call rproc->ops->mmap to create shared memory io - * TODO:get shared memory from mcs device - */ - ret = init_shmem_pool(client, client->static_mem_base, client->static_mem_size); - if (ret){ - close(mcs_fd); - syslog(LOG_ERR, "init shared memory pool failed, err %d\n", ret); - return NULL; + ret = rproc_register_notifier(); + if (ret) { + syslog(LOG_ERR, "unable to register notifier, err: %d\n", ret); + goto err; } return rproc; -} - -static void rproc_remove(struct remoteproc *rproc) -{ +err: close(mcs_fd); - rproc->priv = NULL; + return NULL; } static void *rproc_mmap(struct remoteproc *rproc, @@ -204,7 +257,24 @@ static int rproc_config(struct remoteproc *rproc, void *data) size_t rsc_size = 0; void *limg_info = NULL; void *rsc_table = NULL; + struct mem_info info; struct metal_io_region *io = NULL; + struct mica_client *client = rproc->priv; + + /* + * Call rproc->ops->mmap to create shared memory io + */ + ret = ioctl(mcs_fd, IOC_QUERY_MEM, &info); + if (ret < 0) { + syslog(LOG_ERR, "unable to get shared memory information from mcs device, err: %d\n", ret); + return ret; + } + + ret = init_shmem_pool(client, info.phy_addr + (client->cpu_id * SHM_POOL_SIZE), SHM_POOL_SIZE); + if (ret) { + syslog(LOG_ERR, "init shared memory pool failed, err %d\n", ret); + return ret; + } /* parse executable headers */ fseek(image->file, 0, SEEK_END); @@ -307,14 +377,41 @@ static int rproc_start(struct remoteproc *rproc) static int rproc_shutdown(struct remoteproc *rproc) { - /* TODO: - * Delete all the registered remoteproc memories - * and tell clientos shut itself down by PSCI - */ - DEBUG_PRINT("shutdown rproc\n"); + struct remoteproc_mem *mem; + struct metal_list *node; + struct resource_table *rsc_table = rproc->rsc_table; + + /* Tell clientos shut itself down by PSCI */ + set_cpu_status((struct resource_table *)rsc_table, CPU_OFF_FUNCID); + rproc->ops->notify(rproc, 0); + + /* Delete all the registered remoteproc memories */ + metal_list_for_each(&rproc->mems, node) { + struct metal_list *tmpnode; + + mem = metal_container_of(node, struct remoteproc_mem, node); + munmap(mem->io->virt, mem->io->size); + tmpnode = node; + node = tmpnode->prev; + metal_list_del(tmpnode); + metal_free_memory(mem->io); + metal_free_memory(mem); + } + + rproc->rsc_table = NULL; + rproc->rsc_len = 0; + rproc->bitmap = 0; return 0; } +static void rproc_remove(struct remoteproc *rproc) +{ + if (!notifier) + close(mcs_fd); + + rproc->priv = NULL; +} + static int rproc_notify(struct remoteproc *rproc, uint32_t id) { int ret; diff --git a/library/remoteproc/remoteproc_core.c b/library/remoteproc/remoteproc_core.c index 135d582344332abd0f6ffb9b34768707422b190c..c21705f61f564820b5b5f5238902f9a67d7d7eea 100644 --- a/library/remoteproc/remoteproc_core.c +++ b/library/remoteproc/remoteproc_core.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -19,6 +18,8 @@ */ extern const struct remoteproc_ops rproc_bare_metal_ops; +METAL_DECLARE_LIST(g_client_list); + static int store_open(void *store, const char *path, const void **image_data) { long fsize; @@ -97,25 +98,8 @@ static const struct image_store_ops mem_image_store_ops = .features = SUPPORT_SEEK, }; -static void *wait_client_event(void *arg) -{ - struct mica_client *client = arg; - - if (client->wait_event == NULL) { - syslog(LOG_ERR, "wait_event ops is NULL\n"); - return NULL; - } - - while (client->wait_event() != -1) - remoteproc_get_notification(&client->rproc, 0); - - pthread_exit(NULL); -} - int create_client(struct mica_client *client) { - int ret; - pthread_t thread; struct remoteproc *rproc; const struct remoteproc_ops *ops; @@ -130,21 +114,9 @@ int create_client(struct mica_client *client) return -EINVAL; } - ret = pthread_create(&thread, NULL, wait_client_event, client); - if (ret) - goto err; - - ret = pthread_detach(thread); - if (ret) { - pthread_cancel(thread); - goto err; - } - + metal_list_add_tail(&g_client_list, &client->node); metal_list_init(&client->services); return 0; -err: - remoteproc_remove(&client->rproc); - return ret; } int load_client_image(struct mica_client *client) @@ -174,7 +146,13 @@ int load_client_image(struct mica_client *client) return ret; } - return remoteproc_load(rproc, client->path, &store, &mem_image_store_ops, NULL); + ret = remoteproc_load(rproc, client->path, &store, &mem_image_store_ops, NULL); + if (!rproc->rsc_table) { + syslog(LOG_ERR, "failed to parse rsc table, please check the rsctable\n"); + return -EINVAL; + } + + return ret; } int start_client(struct mica_client *client) @@ -184,11 +162,17 @@ int start_client(struct mica_client *client) return remoteproc_start(rproc); } +void stop_client(struct mica_client *client) +{ + if (client != NULL) + remoteproc_shutdown(&client->rproc); +} + void destory_client(struct mica_client *client) { if (client != NULL) { - remoteproc_shutdown(&client->rproc); remoteproc_remove(&client->rproc); + metal_list_del(&client->node); } } diff --git a/library/rpmsg_device/rpmsg_service.c b/library/rpmsg_device/rpmsg_service.c index e69a864ac260d0d5758a05aad65e06127135ba50..2c388290e5dc67c0acab9c1409038aaba0d455ae 100644 --- a/library/rpmsg_device/rpmsg_service.c +++ b/library/rpmsg_device/rpmsg_service.c @@ -41,18 +41,29 @@ int mica_register_service(struct mica_client *client, struct mica_service *svc) { struct metal_list *node, *tmp_node; struct remote_ept *r_ept; - void *priv = svc->priv; + struct mica_service *new_svc; + void *priv; if (client->rproc.state != RPROC_RUNNING) return -EPERM; - if (svc->init) - svc->init(priv); + new_svc = malloc(sizeof(*new_svc)); + if (!new_svc) + return -ENOMEM; - if (svc->rpmsg_ns_match == NULL) - return 0; + memcpy(new_svc, svc, sizeof(*new_svc)); + priv = new_svc->priv; - if (svc->rpmsg_ns_bind_cb == NULL) { + if (new_svc->init) + new_svc->init(new_svc); + + if (new_svc->rpmsg_ns_match == NULL) + goto out; + + if (new_svc->rpmsg_ns_bind_cb == NULL) { + if (new_svc->remove) + new_svc->remove(new_svc); + free(new_svc); syslog(LOG_ERR, "%s failed: require rpmsg_ns_bind_cb() operation\n", __func__); return -EINVAL; } @@ -61,9 +72,9 @@ int mica_register_service(struct mica_client *client, struct mica_service *svc) metal_list_for_each(&remote_ept_list, node) { r_ept = metal_container_of(node, struct remote_ept, node); - if (svc->rpmsg_ns_match(client->rdev, r_ept->name, r_ept->addr, r_ept->dest_addr, priv)) { - svc->rpmsg_ns_bind_cb(client->rdev, r_ept->name, r_ept->addr, r_ept->dest_addr, priv); - DEBUG_PRINT("binding an already existing service. local: %s, remote: %s\n", svc->name, r_ept->name); + if (new_svc->rpmsg_ns_match(client->rdev, r_ept->name, r_ept->addr, r_ept->dest_addr, priv)) { + new_svc->rpmsg_ns_bind_cb(client->rdev, r_ept->name, r_ept->addr, r_ept->dest_addr, priv); + DEBUG_PRINT("binding an already existing service. local: %s, remote: %s\n", new_svc->name, r_ept->name); tmp_node = node; node = tmp_node->prev; metal_list_del(tmp_node); @@ -71,11 +82,28 @@ int mica_register_service(struct mica_client *client, struct mica_service *svc) } } - DEBUG_PRINT("register service: %s\n", svc->name); - metal_list_add_tail(&client->services, &svc->node); +out: + DEBUG_PRINT("register service: %s\n", new_svc->name); + metal_list_add_tail(&client->services, &new_svc->node); return 0; } +void mica_unregister_all_services(struct mica_client *client) +{ + struct metal_list *node, *tmp_node; + struct mica_service *svc; + + metal_list_for_each(&client->services, node) { + svc = metal_container_of(node, struct mica_service, node); + if (svc->remove) + svc->remove(svc); + tmp_node = node; + node = tmp_node->prev; + metal_list_del(tmp_node); + free(svc); + } +} + void mica_ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest) { struct mica_service *svc; diff --git a/library/rpmsg_device/rpmsg_vdev.c b/library/rpmsg_device/rpmsg_vdev.c index cebf2f6dfa9f7c3a044a0b3e92ef53fdb48892db..180708812ac4b3e62c67b749547f44ba0bc8fa92 100644 --- a/library/rpmsg_device/rpmsg_vdev.c +++ b/library/rpmsg_device/rpmsg_vdev.c @@ -142,3 +142,15 @@ err1: metal_free_memory(rpmsg_vdev); return ret; } + +void release_rpmsg_device(struct mica_client *client) +{ + struct rpmsg_virtio_device *rpmsg_vdev; + + rpmsg_vdev = metal_container_of(client->rdev, struct rpmsg_virtio_device, rdev); + + /* destroy all epts */ + rpmsg_deinit_vdev(rpmsg_vdev); + + remoteproc_remove_virtio(&client->rproc, rpmsg_vdev->vdev); +} diff --git a/mcs_km/mcs_km.c b/mcs_km/mcs_km.c index 73feb846edc77fd4755ae5bcaa20785e9a8497bc..5577d355a43298166acddda5a445b8f3ae78e99a 100644 --- a/mcs_km/mcs_km.c +++ b/mcs_km/mcs_km.c @@ -35,7 +35,8 @@ #define IOC_SENDIPI _IOW(MAGIC_NUMBER, 0, int) #define IOC_CPUON _IOW(MAGIC_NUMBER, 1, int) #define IOC_AFFINITY_INFO _IOW(MAGIC_NUMBER, 2, int) -#define IOC_MAXNR 2 +#define IOC_QUERY_MEM _IOW(MAGIC_NUMBER, 3, int) +#define IOC_MAXNR 3 #define IPI_MCS 8 #define RPROC_MEM_MAX 4 @@ -56,8 +57,8 @@ static int invoke_hvc = 1; * @size: total size of the memory region */ struct mcs_rproc_mem { - phys_addr_t phy_addr; - size_t size; + u64 phy_addr; + u64 size; }; static struct mcs_rproc_mem mem[RPROC_MEM_MAX]; @@ -209,8 +210,11 @@ static long mcs_ioctl(struct file *f, unsigned int cmd, unsigned long arg) return -EINVAL; if (_IOC_NR(cmd) > IOC_MAXNR) return -EINVAL; - if (copy_from_user(&info, (struct cpu_info __user *)arg, sizeof(info))) - return -EFAULT; + if (cmd != IOC_QUERY_MEM) { + ret = copy_from_user(&info, (struct cpu_info __user *)arg, sizeof(info)); + if (ret) + return -EFAULT; + } switch (cmd) { case IOC_SENDIPI: @@ -248,6 +252,11 @@ static long mcs_ioctl(struct file *f, unsigned int cmd, unsigned long arg) } break; + case IOC_QUERY_MEM: + if (copy_to_user((void __user *)arg, &mem[0], sizeof(mem[0]))) + return -EFAULT; + break; + default: pr_err("IOC param invalid(0x%x)\n", cmd); return -EINVAL; diff --git a/mica/micad/main.c b/mica/micad/main.c index 93c4b16ad076d465475c973dcbe221070adebce4..c3085f85d89dda056c92acb01482c9718bccf1ca 100644 --- a/mica/micad/main.c +++ b/mica/micad/main.c @@ -189,7 +189,7 @@ int main(int argc, char **argv) { int ret; - daemonize(); + // daemonize(); ret = add_signal_handler(); if (ret) diff --git a/mica/micad/services/rpmsg_pty.c b/mica/micad/services/rpmsg_pty.c index 3b18f9950f8a31b11faaed607934e0f1f2f6d99e..9c820d0cd5de62e8f442f19ab0dc511e44749281 100644 --- a/mica/micad/services/rpmsg_pty.c +++ b/mica/micad/services/rpmsg_pty.c @@ -23,10 +23,9 @@ static int tty_id[RPMSG_TTY_MAX_DEV] = { [ 0 ... (RPMSG_TTY_MAX_DEV-1) ] = -1 }; -static METAL_DECLARE_LIST(tty_dev_list); struct rpmsg_tty_service { - int active; + atomic_int active; struct rpmsg_endpoint ept; int pty_master_fd; int pty_slave_fd; @@ -37,16 +36,20 @@ struct rpmsg_tty_service static void rpmsg_tty_unbind(struct rpmsg_endpoint *ept) { - struct rpmsg_tty_service *svc = ept->priv; - - svc->active = 0; - rpmsg_destroy_ept(ept); - tty_id[svc->tty_index] = -1; - unlink(svc->tty_dev); - close(svc->pty_master_fd); - close(svc->pty_slave_fd); - metal_list_del(&svc->node); - free(svc); + struct rpmsg_tty_service *tty_svc = ept->priv; + + metal_list_del(&tty_svc->node); + rpmsg_destroy_ept(&tty_svc->ept); + tty_id[tty_svc->tty_index] = -1; + unlink(tty_svc->tty_dev); + + close(tty_svc->pty_master_fd); + close(tty_svc->pty_slave_fd); + tty_svc->pty_master_fd = -1; + tty_svc->pty_slave_fd = -1; + + /* stop rpmsg_tty_tx_task */ + tty_svc->active = 0; } static int rpmsg_tty_new_index(void) @@ -67,7 +70,7 @@ static int rpmsg_tty_new_index(void) * opens an unused pseudo terminal, and create a link to this * with the name RPMSG_TTY_DEV. */ -static int create_tty_device(struct rpmsg_tty_service *svc) +static int create_tty_device(struct rpmsg_tty_service *tty_svc) { int ret; int master_fd, slave_fd; @@ -76,8 +79,7 @@ static int create_tty_device(struct rpmsg_tty_service *svc) ret = rpmsg_tty_new_index(); if (ret == -1) return ret; - - svc->tty_index = ret; + tty_svc->tty_index = ret; ret = posix_openpt(O_RDWR | O_NOCTTY); if (ret == -1) @@ -96,11 +98,11 @@ static int create_tty_device(struct rpmsg_tty_service *svc) if (ret != 0) goto err; - snprintf(svc->tty_dev, RPMSG_TTY_DEV_LEN, "%s%d", - RPMSG_TTY_DEV, svc->tty_index); + snprintf(tty_svc->tty_dev, RPMSG_TTY_DEV_LEN, "%s%d", + RPMSG_TTY_DEV, tty_svc->tty_index); - unlink(svc->tty_dev); - ret = symlink(pts_name, svc->tty_dev); + unlink(tty_svc->tty_dev); + ret = symlink(pts_name, tty_svc->tty_dev); if (ret != 0) goto err; @@ -111,12 +113,12 @@ static int create_tty_device(struct rpmsg_tty_service *svc) goto err; } - svc->pty_master_fd = master_fd; - svc->pty_slave_fd = slave_fd; + tty_svc->pty_master_fd = master_fd; + tty_svc->pty_slave_fd = slave_fd; return ret; err: close(master_fd); - tty_id[svc->tty_index] = -1; + tty_id[tty_svc->tty_index] = -1; return ret; } @@ -127,15 +129,15 @@ static int rpmsg_rx_tty_callback(struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv) { int ret; - struct rpmsg_tty_service *svc = priv; + struct rpmsg_tty_service *tty_svc = priv; - if (svc->active != 1) + if (tty_svc->active != 1) return -EAGAIN; while (len) { - ret = write(svc->pty_master_fd, data, len); + ret = write(tty_svc->pty_master_fd, data, len); if (ret < 0) { - fprintf(stderr, "write %s error:%d\n", svc->tty_dev, ret); + fprintf(stderr, "write %s error:%d\n", tty_svc->tty_dev, ret); break; } len -= ret; @@ -151,16 +153,16 @@ static int rpmsg_rx_tty_callback(struct rpmsg_endpoint *ept, void *data, void *rpmsg_tty_tx_task(void *arg) { int ret; - struct rpmsg_tty_service *svc = arg; + struct rpmsg_tty_service *tty_svc = arg; char buf[BUF_SIZE]; struct pollfd fds = { - .fd = svc->pty_master_fd, + .fd = tty_svc->pty_master_fd, .events = POLLIN }; - svc->active = 1; + tty_svc->active = 1; - while (svc->active) { + while (tty_svc->active) { ret = poll(&fds, 1, -1); if (ret == -1) { fprintf(stderr, "%s failed: %s\n", __func__, strerror(errno)); @@ -168,13 +170,13 @@ void *rpmsg_tty_tx_task(void *arg) } if (fds.revents & POLLIN) { - ret = read(svc->pty_master_fd, buf, BUF_SIZE); + ret = read(tty_svc->pty_master_fd, buf, BUF_SIZE); if (ret <= 0) { fprintf(stderr, "shell_user: get from ptmx failed: %d\n", ret); break; } - ret = rpmsg_send(&svc->ept, buf, ret); + ret = rpmsg_send(&tty_svc->ept, buf, ret); if (ret < 0) { fprintf(stderr, "%s: rpmsg_send failed: %d\n", __func__, ret); break; @@ -182,9 +184,10 @@ void *rpmsg_tty_tx_task(void *arg) } } - if (svc->active) - rpmsg_tty_unbind(&svc->ept); + if (tty_svc->active) + rpmsg_tty_unbind(&tty_svc->ept); + free(tty_svc); pthread_exit(NULL); } @@ -198,6 +201,7 @@ static void rpmsg_tty_init(struct rpmsg_device *rdev, const char *name, int ret; pthread_t tty_thread; struct rpmsg_tty_service *tty_svc; + struct metal_list *tty_dev_list = priv; tty_svc = malloc(sizeof(struct rpmsg_tty_service)); if (!tty_svc) @@ -217,7 +221,7 @@ static void rpmsg_tty_init(struct rpmsg_device *rdev, const char *name, * If the ept is successfully created, append the device to tty_dev_list * to make it easier to get the associated device. */ - metal_list_add_tail(&tty_dev_list, &tty_svc->node); + metal_list_add_tail(tty_dev_list, &tty_svc->node); /* Create a tx task to listen for a pty and send pty messages to the remote */ ret = pthread_create(&tty_thread, NULL, rpmsg_tty_tx_task, tty_svc); @@ -263,16 +267,47 @@ static void get_rpmsg_tty_dev(char *str, size_t size, void *priv) { struct rpmsg_tty_service *tty_svc; struct metal_list *node; + struct metal_list *tty_dev_list = priv; - metal_list_for_each(&tty_dev_list, node) { + metal_list_for_each(tty_dev_list, node) { tty_svc = metal_container_of(node, struct rpmsg_tty_service, node); snprintf(str + strlen(str), size - strlen(str), "%s(%s) ", tty_svc->ept.name, tty_svc->tty_dev); } } +static int create_tty_dev_lists(struct mica_service *svc) +{ + svc->priv = malloc(sizeof(struct metal_list)); + if (!svc->priv) + return -ENOMEM; + + metal_list_init((struct metal_list *)svc->priv); + return 0; +} + +static void remove_tty_dev_lists(struct mica_service *svc) +{ + struct rpmsg_tty_service *tty_svc; + struct metal_list *node, *tmp_node; + struct metal_list *tty_dev_list = svc->priv; + + /* unbind all services */ + metal_list_for_each(tty_dev_list, node) { + tty_svc = metal_container_of(node, struct rpmsg_tty_service, node); + tmp_node = node; + node = tmp_node->prev; + rpmsg_tty_unbind(&tty_svc->ept); + } + + free(svc->priv); + svc->priv = NULL; +} + static struct mica_service rpmsg_tty_service = { .name = RPMSG_TTY_NAME, + .init = create_tty_dev_lists, + .remove = remove_tty_dev_lists, .rpmsg_ns_match = rpmsg_tty_match, .rpmsg_ns_bind_cb = rpmsg_tty_init, .get_match_device = get_rpmsg_tty_dev, diff --git a/mica/micad/socket_listener.c b/mica/micad/socket_listener.c index be7306d91b2dc4e57ba08fa5b5faa6d91f069db6..43fe6228e5cc631c44ccdfea585aa433c4f850dc 100644 --- a/mica/micad/socket_listener.c +++ b/mica/micad/socket_listener.c @@ -178,11 +178,11 @@ static int check_create_msg(struct create_msg msg, int msg_fd) return -EINVAL; } - if (msg.cpu < 0 || msg.cpu > sysconf(_SC_NPROCESSORS_ONLN)) { + if (msg.cpu < 0 || msg.cpu >= sysconf(_SC_NPROCESSORS_CONF)) { syslog(LOG_ERR, "Invalid CPUID: %d, out of range(0-%ld)", - msg.cpu, sysconf(_SC_NPROCESSORS_ONLN)); + msg.cpu, sysconf(_SC_NPROCESSORS_CONF) - 1); send_log(msg_fd, "Invalid CPUID: %d, out of range(0-%ld)", - msg.cpu, sysconf(_SC_NPROCESSORS_ONLN)); + msg.cpu, sysconf(_SC_NPROCESSORS_CONF) - 1); return -EINVAL; } @@ -248,7 +248,8 @@ static int client_ctrl_handler(int epoll_fd, void *data) } } else if (strncmp(msg, "stop", CTRL_MSG_SIZE) == 0) { syslog(LOG_INFO, "Stopping %s", unit->client->path); - // TODO: Add stop + mica_stop(unit->client); + ret = 0; } else if (strncmp(msg, "status", CTRL_MSG_SIZE) == 0) { show_status(msg_fd, unit); ret = 0; @@ -306,10 +307,6 @@ static int create_mica_client(int epoll_fd, void *data) strlcpy(client->path, msg.path, MAX_FIRMWARE_PATH_LEN); client->mode = RPROC_MODE_BARE_METAL; - /* TODO: support multi client */ - client->static_mem_base = 0x70000000; - client->static_mem_size = 0x30000; - ret = mica_create(client); if (ret < 0) { syslog(LOG_ERR, "Failed to create mica client, ret: %d", ret); diff --git a/rtos/arm64/qemu-zephyr-image.bin b/rtos/arm64/qemu-zephyr-image.bin deleted file mode 100755 index dc7969a314537b27d293c11277d66a2da61035ec..0000000000000000000000000000000000000000 Binary files a/rtos/arm64/qemu-zephyr-image.bin and /dev/null differ diff --git a/rtos/arm64/qemu-zephyr-rproc.elf b/rtos/arm64/qemu-zephyr-rproc.elf index 056470b0c72251f6fb5326fe0c407e19a62be713..bb7fcbd112bd63518deba2665ef1284ad65844d1 100755 Binary files a/rtos/arm64/qemu-zephyr-rproc.elf and b/rtos/arm64/qemu-zephyr-rproc.elf differ