summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--components/drivers/sdio/block_dev.c225
-rw-r--r--components/finsh/cmd.c8
-rw-r--r--components/finsh/msh_file.c29
-rw-r--r--components/libc/posix/io/stdio/libc.c33
-rw-r--r--components/lwp/lwp.c14
-rw-r--r--components/lwp/lwp.h4
-rw-r--r--components/lwp/lwp_ipc.c1
-rw-r--r--components/lwp/lwp_pid.c5
-rw-r--r--components/lwp/lwp_sys_socket.h39
-rw-r--r--components/lwp/lwp_syscall.c183
-rw-r--r--components/net/lwip/lwip-2.1.2/src/core/netif.c3
-rw-r--r--components/net/sal/socket/net_sockets.c4
-rw-r--r--components/net/sal/src/sal_socket.c311
-rw-r--r--include/rtdef.h2
-rw-r--r--libcpu/aarch64/common/backtrace.c131
-rw-r--r--libcpu/aarch64/common/backtrace.h6
-rw-r--r--libcpu/aarch64/common/context_gcc.S30
-rw-r--r--libcpu/aarch64/common/trap.c13
-rw-r--r--src/kservice.c7
19 files changed, 968 insertions, 80 deletions
diff --git a/components/drivers/sdio/block_dev.c b/components/drivers/sdio/block_dev.c
index 1cdcec22b0..5bbdbb6696 100644
--- a/components/drivers/sdio/block_dev.c
+++ b/components/drivers/sdio/block_dev.c
@@ -10,6 +10,7 @@
#include <rtthread.h>
#include <dfs_fs.h>
+#include <dfs_file.h>
#include <drivers/mmcsd_core.h>
#include <drivers/gpt.h>
@@ -25,6 +26,8 @@
static rt_list_t blk_devices = RT_LIST_OBJECT_INIT(blk_devices);
#define BLK_MIN(a, b) ((a) < (b) ? (a) : (b))
+#define RT_DEVICE_CTRL_BLK_SSIZEGET 0x1268 /**< get number of bytes per sector */
+#define RT_DEVICE_CTRL_ALL_BLK_SSIZEGET 0x80081272 /**< get number of bytes per sector * sector counts*/
struct mmcsd_blk_device
{
@@ -267,6 +270,7 @@ static rt_err_t rt_mmcsd_close(rt_device_t dev)
static rt_err_t rt_mmcsd_control(rt_device_t dev, int cmd, void *args)
{
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
+
switch (cmd)
{
case RT_DEVICE_CTRL_BLK_GETGEOME:
@@ -274,6 +278,16 @@ static rt_err_t rt_mmcsd_control(rt_device_t dev, int cmd, void *args)
break;
case RT_DEVICE_CTRL_BLK_PARTITION:
rt_memcpy(args, &blk_dev->part, sizeof(struct dfs_partition));
+ break;
+ case RT_DEVICE_CTRL_BLK_SSIZEGET:
+ rt_memcpy(args, &blk_dev->geometry.bytes_per_sector, sizeof(rt_uint32_t));
+ break;
+ case RT_DEVICE_CTRL_ALL_BLK_SSIZEGET:
+ {
+ rt_uint64_t count_mul_per = blk_dev->geometry.bytes_per_sector * blk_dev->geometry.sector_count;
+ rt_memcpy(args, &count_mul_per, sizeof(rt_uint64_t));
+ }
+ break;
default:
break;
}
@@ -414,6 +428,207 @@ const static struct rt_device_ops mmcsd_blk_ops =
};
#endif
+#ifdef RT_USING_DFS_V2
+
+static ssize_t rt_mmcsd_fops_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
+{
+ int result = 0;
+ rt_device_t dev = (rt_device_t)file->vnode->data;
+ struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
+ int bytes_per_sector = blk_dev->geometry.bytes_per_sector;
+ int blk_pos = *pos / bytes_per_sector;
+ int first_offs = *pos % bytes_per_sector;
+ char *rbuf;
+ int rsize = 0;
+
+ rbuf = rt_malloc(bytes_per_sector);
+ if (!rbuf)
+ {
+ return 0;
+ }
+
+ /*
+ ** #1: read first unalign block size.
+ */
+ result = rt_mmcsd_read(dev, blk_pos, rbuf, 1);
+ if (result != 1)
+ {
+ rt_free(rbuf);
+ return 0;
+ }
+
+ if (count > bytes_per_sector - first_offs)
+ {
+ rsize = bytes_per_sector - first_offs;
+ }
+ else
+ {
+ rsize = count;
+ }
+ rt_memcpy(buf, rbuf + first_offs, rsize);
+ blk_pos++;
+
+ /*
+ ** #2: read continuous block size.
+ */
+ while (rsize < count)
+ {
+ result = rt_mmcsd_read(dev, blk_pos++, rbuf, 1);
+ if (result != 1)
+ {
+ break;
+ }
+
+ if (count - rsize >= bytes_per_sector)
+ {
+ rt_memcpy(buf + rsize, rbuf, bytes_per_sector);
+ rsize += bytes_per_sector;
+ }
+ else
+ {
+ rt_memcpy(buf + rsize, rbuf, count - rsize);
+ rsize = count;
+ }
+ }
+
+ rt_free(rbuf);
+ *pos += rsize;
+
+ return rsize;
+}
+
+static int rt_mmcsd_fops_ioctl(struct dfs_file *file, int cmd, void *arg)
+{
+ rt_device_t dev = (rt_device_t)file->vnode->data;
+
+ return rt_mmcsd_control(dev,cmd,arg);
+}
+
+static int rt_mmcsd_fops_open(struct dfs_file *file)
+{
+ rt_device_t dev = (rt_device_t)file->vnode->data;
+ rt_mmcsd_control(dev, RT_DEVICE_CTRL_ALL_BLK_SSIZEGET, &file->vnode->size);
+ return RT_EOK;
+}
+
+static int rt_mmcsd_fops_close(struct dfs_file *file)
+{
+ return RT_EOK;
+}
+
+static ssize_t rt_mmcsd_fops_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
+{
+ int result = 0;
+ rt_device_t dev = (rt_device_t)file->vnode->data;
+ struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
+ int bytes_per_sector = blk_dev->geometry.bytes_per_sector;
+ int blk_pos = *pos / bytes_per_sector;
+ int first_offs = *pos % bytes_per_sector;
+ char *rbuf = 0;
+ int wsize = 0;
+
+ /*
+ ** #1: write first unalign block size.
+ */
+ if (first_offs != 0)
+ {
+ if (count > bytes_per_sector - first_offs)
+ {
+ wsize = bytes_per_sector - first_offs;
+ }
+ else
+ {
+ wsize = count;
+ }
+
+ rbuf = rt_malloc(bytes_per_sector);
+ if (!rbuf)
+ {
+ return 0;
+ }
+
+ result = rt_mmcsd_read(dev, blk_pos, rbuf, 1);
+ if (result != 1)
+ {
+ rt_free(rbuf);
+ return 0;
+ }
+
+ rt_memcpy(rbuf + first_offs, buf, wsize);
+ result = rt_mmcsd_write(dev, blk_pos, rbuf, 1);
+ if (result != 1)
+ {
+ rt_free(rbuf);
+ return 0;
+ }
+ rt_free(rbuf);
+ blk_pos += 1;
+ }
+
+ /*
+ ** #2: write continuous block size.
+ */
+ if ((count - wsize) / bytes_per_sector != 0)
+ {
+ result = rt_mmcsd_write(dev, blk_pos, buf + wsize, (count - wsize) / bytes_per_sector);
+ wsize += result * bytes_per_sector;
+ blk_pos += result;
+ if (result != (count - wsize) / bytes_per_sector)
+ {
+ *pos += wsize;
+ return wsize;
+ }
+ }
+
+ /*
+ ** # 3: write last unalign block size.
+ */
+ if ((count - wsize) != 0)
+ {
+ rbuf = rt_malloc(bytes_per_sector);
+ if (rbuf != RT_NULL)
+ {
+ result = rt_mmcsd_read(dev, blk_pos, rbuf, 1);
+ if (result == 1)
+ {
+ rt_memcpy(rbuf, buf + wsize, count - wsize);
+ result = rt_mmcsd_write(dev, blk_pos, rbuf, 1);
+ if (result == 1)
+ {
+ wsize += count - wsize;
+ }
+ }
+
+ rt_free(rbuf);
+ }
+ }
+
+ *pos += wsize;
+ return wsize;
+}
+
+static int rt_mmcsd_fops_poll(struct dfs_file *file, struct rt_pollreq *req)
+{
+ int mask = 0;
+
+ return mask;
+}
+
+const static struct dfs_file_ops mmcsd_blk_fops =
+{
+ rt_mmcsd_fops_open,
+ rt_mmcsd_fops_close,
+ rt_mmcsd_fops_ioctl,
+ rt_mmcsd_fops_read,
+ rt_mmcsd_fops_write,
+ RT_NULL,
+ generic_dfs_lseek,
+ RT_NULL,
+ RT_NULL,
+ rt_mmcsd_fops_poll
+};
+#endif
+
rt_int32_t gpt_device_probe(struct rt_mmcsd_card *card)
{
rt_int32_t err = RT_EOK;
@@ -460,6 +675,11 @@ rt_int32_t gpt_device_probe(struct rt_mmcsd_card *card)
rt_device_register(&(blk_dev->dev), card->host->name,
RT_DEVICE_FLAG_RDWR);
+#ifdef RT_USING_POSIX_DEVIO
+#ifdef RT_USING_DFS_V2
+ blk_dev->dev.fops = &mmcsd_blk_fops;
+#endif
+#endif
rt_list_insert_after(&blk_devices, &blk_dev->list);
for (i = 0; i < RT_GPT_PARTITION_MAX; i++)
@@ -505,6 +725,11 @@ rt_int32_t gpt_device_probe(struct rt_mmcsd_card *card)
rt_device_register(&(blk_dev->dev), dname,
RT_DEVICE_FLAG_RDWR);
+#ifdef RT_USING_POSIX_DEVIO
+#ifdef RT_USING_DFS_V2
+ blk_dev->dev.fops = &mmcsd_blk_fops;
+#endif
+#endif
rt_list_insert_after(&blk_devices, &blk_dev->list);
}
else
diff --git a/components/finsh/cmd.c b/components/finsh/cmd.c
index eba5a0c1d9..c3b0760f6a 100644
--- a/components/finsh/cmd.c
+++ b/components/finsh/cmd.c
@@ -159,18 +159,25 @@ long list_thread(void)
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t *)RT_NULL;
const char *item_title = "thread";
+ const size_t tcb_strlen = sizeof(void *) * 2 + 2;
int maxlen;
list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
+ rt_kprintf("%-*.*s ", tcb_strlen, tcb_strlen, "rt_thread_t");
+
#ifdef RT_USING_SMP
rt_kprintf("%-*.*s cpu bind pri status sp stack size max used left tick error\n", maxlen, maxlen, item_title);
+ object_split(tcb_strlen);
+ rt_kprintf(" ");
object_split(maxlen);
rt_kprintf(" --- ---- --- ------- ---------- ---------- ------ ---------- ---\n");
#else
rt_kprintf("%-*.*s pri status sp stack size max used left tick error\n", maxlen, maxlen, item_title);
+ object_split(tcb_strlen);
+ rt_kprintf(" ");
object_split(maxlen);
rt_kprintf(" --- ------- ---------- ---------- ------ ---------- ---\n");
#endif /*RT_USING_SMP*/
@@ -202,6 +209,7 @@ long list_thread(void)
rt_uint8_t stat;
rt_uint8_t *ptr;
+ rt_kprintf("%p ", thread);
#ifdef RT_USING_SMP
if (thread->oncpu != RT_CPU_DETACHED)
rt_kprintf("%-*.*s %3d %3d %4d ", maxlen, RT_NAME_MAX, thread->parent.name, thread->oncpu, thread->bind_cpu, thread->current_priority);
diff --git a/components/finsh/msh_file.c b/components/finsh/msh_file.c
index 5c38b579b1..a47ae73f05 100644
--- a/components/finsh/msh_file.c
+++ b/components/finsh/msh_file.c
@@ -618,6 +618,7 @@ MSH_CMD_EXPORT_ALIAS(cmd_mount, mount, mount <device> <mountpoint> <fstype>);
/* unmount the filesystem from the specified mountpoint */
static int cmd_umount(int argc, char **argv)
{
+#ifndef RT_USING_DFS_V2
char *path = argv[1];
if (argc != 2)
@@ -637,6 +638,34 @@ static int cmd_umount(int argc, char **argv)
rt_kprintf("succeed!\n");
return 0;
}
+#else
+ int flags = 0;
+ char *path = argv[1];
+
+ if (argc < 2)
+ {
+ rt_kprintf("Usage: unmount [-f] <mountpoint>.\n");
+ return -1;
+ }
+
+ if (argc > 2)
+ {
+ flags = strcmp(argv[1], "-f") == 0 ? MNT_FORCE : 0;
+ path = argv[2];
+ }
+
+ rt_kprintf("unmount %s ... ", path);
+ if (dfs_umount(path, flags) < 0)
+ {
+ rt_kprintf("failed!\n");
+ return -1;
+ }
+ else
+ {
+ rt_kprintf("succeed!\n");
+ return 0;
+ }
+#endif
}
MSH_CMD_EXPORT_ALIAS(cmd_umount, umount, Unmount the mountpoint);
diff --git a/components/libc/posix/io/stdio/libc.c b/components/libc/posix/io/stdio/libc.c
index 9c7d28fefd..522ff36510 100644
--- a/components/libc/posix/io/stdio/libc.c
+++ b/components/libc/posix/io/stdio/libc.c
@@ -30,39 +30,20 @@ int libc_system_init(void)
dev_console = rt_console_get_device();
if (dev_console)
{
- int fd, ret;
- char name[STDIO_DEVICE_NAME_MAX];
-
- rt_snprintf(name, sizeof(name) - 1, "/dev/%s", dev_console->parent.name);
- name[STDIO_DEVICE_NAME_MAX - 1] = '\0';
-
- fd = open(name, O_RDWR);
- if (fd >= 0)
- {
- /* set fd (0, 1, 2) */
- ret = sys_dup2(fd, 0);
- if (ret != fd)
- {
- close(fd);
- }
- sys_dup2(ret, 1);
- sys_dup2(ret, 2);
-
- ret = libc_stdio_set_console(dev_console->parent.name, O_RDWR);
- if (ret < 0)
- {
- return -1;
- }
- }
- else
+ int fd = libc_stdio_set_console(dev_console->parent.name, O_RDWR);
+ if (fd < 0)
{
return -1;
}
+ /* set fd (0, 1, 2) */
+ sys_dup2(fd, 0);
+ sys_dup2(fd, 1);
+ sys_dup2(fd, 2);
}
#endif /* RT_USING_POSIX_STDIO */
return 0;
}
-INIT_APP_EXPORT(libc_system_init);
+INIT_ENV_EXPORT(libc_system_init);
#if defined(RT_USING_POSIX_STDIO) && defined(RT_USING_NEWLIBC)
diff --git a/components/lwp/lwp.c b/components/lwp/lwp.c
index c27f4ca172..96ebdd866c 100644
--- a/components/lwp/lwp.c
+++ b/components/lwp/lwp.c
@@ -1403,3 +1403,17 @@ void lwp_user_setting_restore(rt_thread_t thread)
}
}
#endif /* ARCH_MM_MMU */
+
+void lwp_uthread_ctx_save(void *ctx)
+{
+ rt_thread_t thread;
+ thread = rt_thread_self();
+ thread->user_ctx.ctx = ctx;
+}
+
+void lwp_uthread_ctx_restore(void)
+{
+ rt_thread_t thread;
+ thread = rt_thread_self();
+ thread->user_ctx.ctx = RT_NULL;
+}
diff --git a/components/lwp/lwp.h b/components/lwp/lwp.h
index 2924a99c81..841ce7725e 100644
--- a/components/lwp/lwp.h
+++ b/components/lwp/lwp.h
@@ -164,6 +164,10 @@ void lwp_aspace_switch(struct rt_thread *thread);
#endif
void lwp_user_setting_save(rt_thread_t thread);
void lwp_user_setting_restore(rt_thread_t thread);
+
+void lwp_uthread_ctx_save(void *ctx);
+void lwp_uthread_ctx_restore(void);
+
int lwp_setaffinity(pid_t pid, int cpu);
/* ctime lwp API */
diff --git a/components/lwp/lwp_ipc.c b/components/lwp/lwp_ipc.c
index a4b560e264..60e216565c 100644
--- a/components/lwp/lwp_ipc.c
+++ b/components/lwp/lwp_ipc.c
@@ -980,6 +980,7 @@ int lwp_channel_open(int fdt_type, const char *name, int flags)
{
/* initialize vnode */
dfs_vnode_init(d->vnode, FT_USER, &channel_fops);
+ d->flags = O_RDWR; /* set flags as read and write */
/* set socket to the data of dfs_file */
d->vnode->data = (void *)ch;
diff --git a/components/lwp/lwp_pid.c b/components/lwp/lwp_pid.c
index 82185adf34..79f4e2ec0f 100644
--- a/components/lwp/lwp_pid.c
+++ b/components/lwp/lwp_pid.c
@@ -106,6 +106,11 @@ static void lwp_pid_put(pid_t pid)
rt_base_t level;
struct lwp_avl_struct *p;
+ if (pid == 0)
+ {
+ return;
+ }
+
level = rt_hw_interrupt_disable();
p = lwp_avl_find(pid, lwp_pid_root);
if (p)
diff --git a/components/lwp/lwp_sys_socket.h b/components/lwp/lwp_sys_socket.h
index ea73082c31..527d5ebbe8 100644
--- a/components/lwp/lwp_sys_socket.h
+++ b/components/lwp/lwp_sys_socket.h
@@ -94,4 +94,43 @@
#define INTF_IPV6_V6ONLY 26
#define IMPL_IPV6_V6ONLY 27
+struct musl_sockaddr
+{
+ uint16_t sa_family;
+ char sa_data[14];
+};
+
+struct musl_ifmap {
+ unsigned long int mem_start;
+ unsigned long int mem_end;
+ unsigned short int base_addr;
+ unsigned char irq;
+ unsigned char dma;
+ unsigned char port;
+};
+
+struct musl_ifreq
+{
+ union
+ {
+#define IFNAMSIZ 16
+ char ifrn_name[IFNAMSIZ];
+ } ifr_ifrn;
+ union
+ {
+ struct musl_sockaddr ifru_addr;
+ struct musl_sockaddr ifru_dstaddr;
+ struct musl_sockaddr ifru_broadaddr;
+ struct musl_sockaddr ifru_netmask;
+ struct musl_sockaddr ifru_hwaddr;
+ short int ifru_flags;
+ int ifru_ivalue;
+ int ifru_mtu;
+ struct musl_ifmap ifru_map;
+ char ifru_slave[IFNAMSIZ];
+ char ifru_newname[IFNAMSIZ];
+ char *ifru_data;
+ } ifr_ifru;
+};
+
#endif /* __LWP_SYS_SOCKET_H__ */
diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c
index bffd951a56..547d333f48 100644
--- a/components/lwp/lwp_syscall.c
+++ b/components/lwp/lwp_syscall.c
@@ -103,12 +103,6 @@
#error "No definition RT_USING_POSIX_CLOCK"
#endif /* RT_USING_POSIX_CLOCK */
-struct musl_sockaddr
-{
- uint16_t sa_family;
- char sa_data[14];
-};
-
void lwp_cleanup(struct rt_thread *tid);
#ifdef ARCH_MM_MMU
@@ -551,7 +545,7 @@ sysret_t sys_open(const char *name, int flag, ...)
#endif
}
-/* syscall: "open" ret: "int" args: "const char *" "mode_t" "mode" */
+/* syscall: "openat" ret: "int" args: "const char *" "mode_t" "mode" */
sysret_t sys_openat(int dirfd, const char *name, int flag, mode_t mode)
{
#ifdef ARCH_MM_MMU
@@ -4684,6 +4678,12 @@ sysret_t sys_sched_setparam(pid_t pid, void *param)
return ret;
}
+sysret_t sys_sched_yield(void)
+{
+ rt_thread_yield();
+ return 0;
+}
+
sysret_t sys_sched_getparam(pid_t pid, void *param)
{
struct sched_param *sched_param = (struct sched_param *)param;
@@ -5378,7 +5378,154 @@ sysret_t sys_epoll_pwait(int fd,
return (ret < 0 ? GET_ERRNO() : ret);
}
-static const struct rt_syscall_def func_table[] =
+sysret_t sys_chmod(const char *fileName, mode_t mode)
+{
+ char *copy_fileName;
+ size_t len_fileName, copy_len_fileName;
+ int err_fileName;
+#ifdef RT_USING_DFS_V2
+ struct dfs_attr attr;
+ attr.st_mode = mode;
+#endif
+ int ret = 0;
+
+ len_fileName = lwp_user_strlen(fileName, &err_fileName);
+ if (err_fileName)
+ {
+ return -EFAULT;
+ }
+
+ copy_fileName = (char*)rt_malloc(len_fileName + 1);
+ if (!copy_fileName)
+ {
+ return -ENOMEM;
+ }
+
+ copy_len_fileName = lwp_get_from_user(copy_fileName, (void *)fileName, len_fileName);
+ copy_fileName[copy_len_fileName] = '\0';
+#ifdef RT_USING_DFS_V2
+ ret = dfs_file_setattr(copy_fileName, &attr);
+#else
+ SET_ERRNO(EFAULT);
+#endif
+ rt_free(copy_fileName);
+
+ return (ret < 0 ? GET_ERRNO() : ret);
+}
+
+sysret_t sys_reboot(int magic)
+{
+ rt_hw_cpu_reset();
+
+ return 0;
+}
+
+ssize_t sys_pread64(int fd, void *buf, int size, off_t offset)
+#ifdef RT_USING_DFS_V2
+{
+ ssize_t pread(int fd, void *buf, size_t len, off_t offset);
+#ifdef ARCH_MM_MMU
+ ssize_t ret = -1;
+ void *kmem = RT_NULL;
+
+ if (!size)
+ {
+ return -EINVAL;
+ }
+
+ if (!lwp_user_accessable((void *)buf, size))
+ {
+ return -EFAULT;
+ }
+ kmem = kmem_get(size);
+ if (!kmem)
+ {
+ return -ENOMEM;
+ }
+
+ ret = pread(fd, kmem, size, offset);
+ if (ret > 0)
+ {
+ lwp_put_to_user(buf, kmem, ret);
+ }
+
+ if (ret < 0)
+ {
+ ret = GET_ERRNO();
+ }
+
+ kmem_put(kmem);
+
+ return ret;
+#else
+ if (!lwp_user_accessable((void *)buf, size))
+ {
+ return -EFAULT;
+ }
+
+ ssize_t ret = pread(fd, kmem, size, offset);
+ return (ret < 0 ? GET_ERRNO() : ret);
+#endif
+}
+#else
+{
+ ssize_t ret = -ENOSYS;
+ return (ret < 0 ? GET_ERRNO() : ret);
+}
+#endif
+
+ssize_t sys_pwrite64(int fd, void *buf, int size, off_t offset)
+#ifdef RT_USING_DFS_V2
+{
+ ssize_t pwrite(int fd, const void *buf, size_t len, off_t offset);
+#ifdef ARCH_MM_MMU
+ ssize_t ret = -1;
+ void *kmem = RT_NULL;
+
+ if (!size)
+ {
+ return -EINVAL;
+ }
+
+ if (!lwp_user_accessable((void *)buf, size))
+ {
+ return -EFAULT;
+ }
+ kmem = kmem_get(size);
+ if (!kmem)
+ {
+ return -ENOMEM;
+ }
+
+ lwp_get_from_user(kmem, (void *)buf, size);
+
+ ret = pwrite(fd, kmem, size, offset);
+ if (ret < 0)
+ {
+ ret = GET_ERRNO();
+ }
+
+ kmem_put(kmem);
+
+ return ret;
+#else
+ if (!lwp_user_accessable((void *)buf, size))
+ {
+ return -EFAULT;
+ }
+
+ ssize_t ret = pwrite(fd, kmem, size, offset);
+ return (ret < 0 ? GET_ERRNO() : ret);
+#endif
+}
+#else
+{
+ ssize_t ret = -ENOSYS;
+ return (ret < 0 ? GET_ERRNO() : ret);
+}
+#endif
+
+const static struct rt_syscall_def func_table[] =
{
SYSCALL_SIGN(sys_exit), /* 01 */
SYSCALL_SIGN(sys_read),
@@ -5600,11 +5747,11 @@ static const struct rt_syscall_def func_table[] =
SYSCALL_SIGN(sys_symlink),
SYSCALL_SIGN(sys_getaffinity), /* 180 */
SYSCALL_SIGN(sys_sysinfo),
- SYSCALL_SIGN(sys_notimpl),
- SYSCALL_SIGN(sys_notimpl),
- SYSCALL_SIGN(sys_notimpl),
- SYSCALL_SIGN(sys_notimpl), /* 185 */
- SYSCALL_SIGN(sys_notimpl),
+ SYSCALL_SIGN(sys_chmod),
+ SYSCALL_SIGN(sys_reboot),
+ SYSCALL_SIGN(sys_sched_yield),
+ SYSCALL_SIGN(sys_pread64), /* 185 */
+ SYSCALL_SIGN(sys_pwrite64),
SYSCALL_SIGN(sys_sigpending),
SYSCALL_SIGN(sys_sigtimedwait),
SYSCALL_SIGN(sys_notimpl),
@@ -5632,7 +5779,10 @@ const void *lwp_get_sys_api(rt_uint32_t number)
}
else
{
- LOG_I("Unimplement syscall %d", number);
+ if (__sys_log_enable)
+ {
+ LOG_I("Unimplement syscall %d", number);
+ }
}
}
@@ -5656,7 +5806,10 @@ const char *lwp_get_syscall_name(rt_uint32_t number)
}
else
{
- LOG_I("Unimplement syscall %d", number);
+ if (__sys_log_enable)
+ {
+ LOG_I("Unimplement syscall %d", number);
+ }
}
}
diff --git a/components/net/lwip/lwip-2.1.2/src/core/netif.c b/components/net/lwip/lwip-2.1.2/src/core/netif.c
index b2b4adf85b..a489c570de 100644
--- a/components/net/lwip/lwip-2.1.2/src/core/netif.c
+++ b/components/net/lwip/lwip-2.1.2/src/core/netif.c
@@ -1763,7 +1763,8 @@ netif_find(const char *name)
return NULL;
}
- num = (u8_t)atoi(&name[2]);
+ /* Out netif's name is e0, e1... */
+ num = (u8_t)atoi(&name[1]);
NETIF_FOREACH(netif) {
if (num == netif->num &&
diff --git a/components/net/sal/socket/net_sockets.c b/components/net/sal/socket/net_sockets.c
index 8f53e744c7..211876c6c4 100644
--- a/components/net/sal/socket/net_sockets.c
+++ b/components/net/sal/socket/net_sockets.c
@@ -52,8 +52,9 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
rt_set_errno(-ENOMEM);
return -1;
}
- rt_memset(d->vnode, 0, sizeof(struct dfs_vnode));
+
dfs_vnode_init(d->vnode, FT_SOCKET, dfs_net_get_fops());
+ d->flags = O_RDWR; /* set flags as read and write */
/* set socket to the data of dfs_file */
d->vnode->data = (void *)(size_t)new_socket;
@@ -258,6 +259,7 @@ int socket(int domain, int type, int protocol)
if (socket >= 0)
{
dfs_vnode_init(d->vnode, FT_SOCKET, dfs_net_get_fops());
+ d->flags = O_RDWR; /* set flags as read and write */
/* set socket to the data of dfs_file */
d->vnode->data = (void *)(size_t)socket;
diff --git a/components/net/sal/src/sal_socket.c b/components/net/sal/src/sal_socket.c
index b73ad749b1..9d343b8c1f 100644
--- a/components/net/sal/src/sal_socket.c
+++ b/components/net/sal/src/sal_socket.c
@@ -26,6 +26,10 @@
#include <ipc/workqueue.h>
#endif
+#ifdef RT_USING_LWP
+#include <lwp_sys_socket.h>
+#endif
+
/* check system workqueue stack size */
#if defined(SAL_INTERNET_CHECK) && RT_SYSTEM_WORKQUEUE_STACKSIZE < 1536
#error "The system workqueue stack size must more than 1536 bytes"
@@ -51,6 +55,16 @@ struct sal_netdev_res_table
struct netdev *netdev;
};
+struct ifconf
+{
+ int ifc_len; /* Size of buffer. */
+ union
+ {
+ char* ifcu_buf;
+ struct sal_ifreq *ifcu_req;
+ } ifc_ifcu;
+};
+
#ifdef SAL_USING_TLS
/* The global TLS protocol options */
static struct sal_proto_tls *proto_tls;
@@ -1028,8 +1042,17 @@ int sal_closesocket(int socket)
return error;
}
+#define ARPHRD_ETHER 1 /* Ethernet 10/100Mbps. */
+#define ARPHRD_LOOPBACK 772 /* Loopback device. */
+#define IFF_UP 0x1
+#define IFF_RUNNING 0x40
+#define IFF_NOARP 0x80
+
int sal_ioctlsocket(int socket, long cmd, void *arg)
{
+ rt_slist_t *node = RT_NULL;
+ struct netdev *netdev = RT_NULL;
+ struct netdev *cur_netdev_list = netdev_list;
struct sal_socket *sock;
struct sal_proto_family *pf;
struct sockaddr_in *addr_in = RT_NULL;
@@ -1048,48 +1071,276 @@ int sal_ioctlsocket(int socket, long cmd, void *arg)
switch (cmd)
{
case SIOCGIFADDR:
- addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_addr);
-#if NETDEV_IPV4 && NETDEV_IPV6
- addr_in->sin_addr.s_addr = sock->netdev->ip_addr.u_addr.ip4.addr;
-#elif NETDEV_IPV4
- addr_in->sin_addr.s_addr = sock->netdev->ip_addr.addr;
-#elif NETDEV_IPV6
-#error "not only support IPV6"
-#endif /* NETDEV_IPV4 && NETDEV_IPV6*/
- return 0;
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
+ {
+ addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_addr);
+ #if NETDEV_IPV4 && NETDEV_IPV6
+ addr_in->sin_addr.s_addr = sock->netdev->ip_addr.u_addr.ip4.addr;
+ #elif NETDEV_IPV4
+ addr_in->sin_addr.s_addr = sock->netdev->ip_addr.addr;
+ #elif NETDEV_IPV6
+ #error "not only support IPV6"
+ #endif /* NETDEV_IPV4 && NETDEV_IPV6*/
+ return 0;
+ }
+ else
+ {
+ if (cur_netdev_list == RT_NULL)
+ {
+ LOG_E("ifconfig: network interface device list error.\n");
+ return -1;
+ }
+
+ for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
+ {
+ netdev = rt_list_entry(node, struct netdev, list);
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
+ {
+ addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_addr);
+ addr_in->sin_addr.s_addr = netdev->ip_addr.addr;
+ return 0;
+ }
+ }
+ return -1;
+ }
case SIOCSIFADDR:
- addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_addr);
- sal_sockaddr_to_ipaddr(addr,&input_ipaddr);
- netdev_set_ipaddr(sock->netdev,&input_ipaddr);
- return 0;
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
+ {
+ addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_addr);
+ sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
+ netdev_set_ipaddr(sock->netdev, &input_ipaddr);
+ return 0;
+ }
+ else
+ {
+ if (cur_netdev_list == RT_NULL)
+ {
+ LOG_E("ifconfig: network interface device list error.\n");
+ return -1;
+ }
+
+ for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
+ {
+ netdev = rt_list_entry(node, struct netdev, list);
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
+ {
+ addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_addr);
+ sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
+ netdev_set_ipaddr(netdev, &input_ipaddr);
+ return 0;
+ }
+ }
+ return -1;
+ }
case SIOCGIFNETMASK:
- addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_netmask);
-#if NETDEV_IPV4 && NETDEV_IPV6
- addr_in->sin_addr.s_addr = sock->netdev->netmask.u_addr.ip4.addr;
-#elif NETDEV_IPV4
- addr_in->sin_addr.s_addr = sock->netdev->netmask.addr;
-#elif NETDEV_IPV6
-#error "not only support IPV6"
-#endif /* NETDEV_IPV4 && NETDEV_IPV6*/
- return 0;
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
+ {
+ addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_netmask);
+ #if NETDEV_IPV4 && NETDEV_IPV6
+ addr_in->sin_addr.s_addr = sock->netdev->netmask.u_addr.ip4.addr;
+ #elif NETDEV_IPV4
+ addr_in->sin_addr.s_addr = sock->netdev->netmask.addr;
+ #elif NETDEV_IPV6
+ #error "not only support IPV6"
+ #endif /* NETDEV_IPV4 && NETDEV_IPV6*/
+ return 0;
+ }
+ else
+ {
+ if (cur_netdev_list == RT_NULL)
+ {
+ LOG_E("ifconfig: network interface device list error.\n");
+ return -1;
+ }
+
+ for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
+ {
+ netdev = rt_list_entry(node, struct netdev, list);
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
+ {
+ addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_netmask);
+ #if NETDEV_IPV4 && NETDEV_IPV6
+ addr_in->sin_addr.s_addr = netdev->netmask.u_addr.ip4.addr;
+ #elif NETDEV_IPV4
+ addr_in->sin_addr.s_addr = netdev->netmask.addr;
+ #elif NETDEV_IPV6
+ #error "not only support IPV6"
+ #endif /* NETDEV_IPV4 && NETDEV_IPV6*/
+ return 0;
+ }
+ }
+ return -1;
+ }
case SIOCSIFNETMASK:
- addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_netmask);
- sal_sockaddr_to_ipaddr(addr,&input_ipaddr);
- netdev_set_netmask(sock->netdev,&input_ipaddr);
- return 0;
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
+ {
+ addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_netmask);
+ sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
+ netdev_set_netmask(sock->netdev, &input_ipaddr);
+ return 0;
+ }
+ else
+ {
+ if (cur_netdev_list == RT_NULL)
+ {
+ LOG_E("ifconfig: network interface device list error.\n");
+ return -1;
+ }
+
+ for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
+ {
+ netdev = rt_list_entry(node, struct netdev, list);
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
+ {
+ addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_netmask);
+ sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
+ netdev_set_netmask(netdev, &input_ipaddr);
+ return 0;
+ }
+ }
+ return -1;
+ }
case SIOCGIFHWADDR:
- addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_hwaddr);
- rt_memcpy(addr->sa_data,sock->netdev->hwaddr,sock->netdev->hwaddr_len);
- return 0;
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name,sock->netdev->name))
+ {
+ addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_hwaddr);
+#ifdef RT_USING_LWP
+ if (!strcmp("lo", sock->netdev->name))
+ {
+ struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
+ musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_LOOPBACK;
+ }
+ else
+ {
+ struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
+ musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
+ }
+#endif
+ rt_memcpy(addr->sa_data, sock->netdev->hwaddr, sock->netdev->hwaddr_len);
+ return 0;
+ }
+ else
+ {
+ if (cur_netdev_list == RT_NULL)
+ {
+ LOG_E("ifconfig: network interface device list error.\n");
+ return -1;
+ }
+
+ for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
+ {
+ netdev = rt_list_entry(node, struct netdev, list);
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
+ {
+ addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_hwaddr);
+#ifdef RT_USING_LWP
+ if (!strcmp("lo", netdev->name))
+ {
+ struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
+ musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_LOOPBACK;
+ }
+ else
+ {
+ struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
+ musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
+ }
+#endif
+ rt_memcpy(addr->sa_data, netdev->hwaddr, netdev->hwaddr_len);
+ return 0;
+ }
+ }
+ return -1;
+ }
case SIOCGIFMTU:
- ifr->ifr_ifru.ifru_mtu = sock->netdev->mtu;
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
+ {
+ ifr->ifr_ifru.ifru_mtu = sock->netdev->mtu;
+ return 0;
+ }
+ else
+ {
+ if (cur_netdev_list == RT_NULL)
+ {
+ LOG_E("ifconfig: network interface device list error.\n");
+ return -1;
+ }
+
+ for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
+ {
+ netdev = rt_list_entry(node, struct netdev, list);
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
+ {
+ ifr->ifr_ifru.ifru_mtu = netdev->mtu;
+ return 0;
+ }
+ }
+ return -1;
+ }
+ case SIOCGIFFLAGS:
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
+ {
+ uint16_t flags_tmp = 0;
+ if (sock->netdev->flags & NETDEV_FLAG_UP)
+ flags_tmp = flags_tmp | IFF_UP;
+ if (!(sock->netdev->flags & NETDEV_FLAG_ETHARP))
+ flags_tmp = flags_tmp | IFF_NOARP;
+ flags_tmp = flags_tmp | IFF_RUNNING;
+ ifr->ifr_ifru.ifru_flags = flags_tmp;
+ return 0;
+ }
+ else
+ {
+ if (cur_netdev_list == RT_NULL)
+ {
+ LOG_E("ifconfig: network interface device list error.\n");
+ return -1;
+ }
+
+ for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
+ {
+ netdev = rt_list_entry(node, struct netdev, list);
+ if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
+ {
+ uint16_t flags_tmp = 0;
+ if (sock->netdev->flags & NETDEV_FLAG_UP)
+ flags_tmp = flags_tmp | IFF_UP;
+ if (!(sock->netdev->flags & NETDEV_FLAG_ETHARP))
+ flags_tmp = flags_tmp | IFF_NOARP;
+ ifr->ifr_ifru.ifru_flags = flags_tmp;
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+
+ case SIOCSIFFLAGS:
+ sock->netdev->flags = ifr->ifr_ifru.ifru_flags;
return 0;
+ case SIOCGIFCONF:
+ {
+ struct ifconf *ifconf_tmp;
+ ifconf_tmp = (struct ifconf *)arg;
+ int count_size = 0;
+ for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
+ {
+ struct sal_ifreq sal_ifreq_temp;
+ count_size++;
+ netdev = rt_list_entry(node, struct netdev, list);
+ rt_strcpy(sal_ifreq_temp.ifr_ifrn.ifrn_name, netdev->name);
+ rt_memcpy(ifconf_tmp->ifc_ifcu.ifcu_buf, &sal_ifreq_temp, sizeof(struct sal_ifreq));
+ ifconf_tmp->ifc_ifcu.ifcu_buf += sizeof(struct sal_ifreq);
+ }
+ ifconf_tmp->ifc_len = sizeof(struct sal_ifreq) * count_size;
+ ifconf_tmp->ifc_ifcu.ifcu_buf = ifconf_tmp->ifc_ifcu.ifcu_buf - sizeof(struct sal_ifreq) * count_size;
+ return 0;
+ }
default:
break;
}
diff --git a/include/rtdef.h b/include/rtdef.h
index f0e975d725..1966595ced 100644
--- a/include/rtdef.h
+++ b/include/rtdef.h
@@ -807,6 +807,8 @@ struct rt_user_context
void *sp;
void *pc;
void *flag;
+
+ void *ctx;
};
#endif
diff --git a/libcpu/aarch64/common/backtrace.c b/libcpu/aarch64/common/backtrace.c
index d8985d0c09..14ea18a97f 100644
--- a/libcpu/aarch64/common/backtrace.c
+++ b/libcpu/aarch64/common/backtrace.c
@@ -6,10 +6,15 @@
* Change Logs:
* Date Author Notes
* 2022-06-02 Jesven the first version
+ * 2023-06-24 WangXiaoyao Support backtrace for non-active thread
*/
+#include "mm_aspace.h"
+#include "mmu.h"
+
#include <rtthread.h>
#include <backtrace.h>
+#include <stdlib.h>
#define BT_NESTING_MAX 100
@@ -19,7 +24,7 @@ static int unwind_frame(struct bt_frame *frame)
if ((fp & 0x7)
#ifdef RT_USING_LWP
- || fp < KERNEL_VADDR_START
+ || (rt_kmem_v2p((void *)fp) == ARCH_MAP_FAILED)
#endif
)
{
@@ -27,16 +32,18 @@ static int unwind_frame(struct bt_frame *frame)
}
frame->fp = *(unsigned long *)fp;
frame->pc = *(unsigned long *)(fp + 8);
+
+ if ((rt_kmem_v2p((void *)frame->pc) == ARCH_MAP_FAILED))
+ return 1;
return 0;
}
static void walk_unwind(unsigned long pc, unsigned long fp)
{
- struct bt_frame frame;
+ struct bt_frame frame = {fp, 1};
unsigned long lr = pc;
int nesting = 0;
- frame.fp = fp;
while (nesting < BT_NESTING_MAX)
{
rt_kprintf(" %p", (void *)lr);
@@ -51,18 +58,128 @@ static void walk_unwind(unsigned long pc, unsigned long fp)
void backtrace(unsigned long pc, unsigned long lr, unsigned long fp)
{
- rt_kprintf("please use: addr2line -e rtthread.elf -a -f %p", (void *)pc);
- walk_unwind(lr, fp);
+ rt_kprintf("please use: addr2line -e rtthread.elf -a -f");
+ if (pc)
+ rt_kprintf(" %p", (void *)pc);
+
+ if (lr && fp)
+ walk_unwind(lr, fp);
rt_kprintf("\n");
}
int rt_backtrace(void)
{
- unsigned long pc = (unsigned long)backtrace;
unsigned long ra = (unsigned long)__builtin_return_address(0U);
unsigned long fr = (unsigned long)__builtin_frame_address(0U);
- backtrace(pc, ra, fr);
+ backtrace(0, ra, fr);
return 0;
}
MSH_CMD_EXPORT_ALIAS(rt_backtrace, bt_test, backtrace test);
+
+#define ARCH_CONTEXT_FETCH(pctx, id) (*(((unsigned long *)pctx) + (id)))
+
+int rt_backtrace_thread(rt_thread_t thread)
+{
+ unsigned long lr;
+ unsigned long fp;
+
+ if (thread == rt_thread_self())
+ {
+ return -RT_EINVAL;
+ }
+ else
+ {
+ lr = ARCH_CONTEXT_FETCH(thread->sp, 3);
+ fp = ARCH_CONTEXT_FETCH(thread->sp, 7);
+ backtrace(0, lr, fp);
+ return 0;
+ }
+}
+
+#ifdef RT_USING_SMART
+
+int rt_backtrace_user_thread(rt_thread_t thread)
+{
+ unsigned long pc;
+ unsigned long lr;
+ unsigned long fp;
+ unsigned long ctx = (unsigned long)thread->user_ctx.ctx;
+
+ if (ctx > (unsigned long)thread->stack_addr
+ && ctx < (unsigned long)thread->stack_addr + thread->stack_size)
+ {
+ pc = ARCH_CONTEXT_FETCH(thread->user_ctx.ctx, 0);
+ lr = ARCH_CONTEXT_FETCH(thread->user_ctx.ctx, 3);
+ fp = ARCH_CONTEXT_FETCH(thread->user_ctx.ctx, 7);
+ backtrace(pc, lr, fp);
+ return 0;
+ }
+ else
+ return -1;
+}
+
+#endif /* RT_USING_SMART */
+
+static long custom_hex_to_long(const char* hex)
+{
+ long result = 0;
+ int i = 0;
+
+ // Skip the "0x" prefix
+ if (hex[0] == '0' && (hex[1] == 'x' || hex[1] == 'X'))
+ {
+ i = 2;
+ }
+
+ // Convert each hex digit to its decimal value
+ for (; hex[i] != '\0'; i++)
+ {
+ char digit = hex[i];
+ if (digit >= '0' && digit <= '9')
+ {
+ result = result * 16 + (digit - '0');
+ }
+ else if (digit >= 'a' && digit <= 'f')
+ {
+ result = result * 16 + (digit - 'a' + 10);
+ }
+ else if (digit >= 'A' && digit <= 'F')
+ {
+ result = result * 16 + (digit - 'A' + 10);
+ }
+ else
+ {
+ // Invalid hex digit
+ return 0;
+ }
+ }
+
+ return result;
+}
+
+static void cmd_backtrace(int argc, char** argv)
+{
+ long pid;
+
+ if (argc < 2)
+ {
+ rt_kprintf("please use: backtrace pid\n");
+ return;
+ }
+
+ if (strncmp(argv[1], "0x", 2) == 0)
+ {
+ pid = custom_hex_to_long(argv[1]);
+ }
+ else
+ {
+ pid = atol(argv[1]);
+ }
+ if (pid)
+ {
+ rt_kprintf("backtrace %s(0x%lx), from %s\n", ((rt_thread_t)pid)->parent.name, pid, argv[1]);
+ rt_backtrace_thread((rt_thread_t)pid);
+ }
+}
+MSH_CMD_EXPORT_ALIAS(cmd_backtrace, backtrace, print backtrace of a thread);
diff --git a/libcpu/aarch64/common/backtrace.h b/libcpu/aarch64/common/backtrace.h
index 8c8006690c..e5e281978c 100644
--- a/libcpu/aarch64/common/backtrace.h
+++ b/libcpu/aarch64/common/backtrace.h
@@ -6,11 +6,14 @@
* Change Logs:
* Date Author Notes
* 2022-06-02 Jesven the first version
+ * 2023-06-24 WangXiaoyao Support backtrace for non-active thread
*/
#ifndef __BACKTRACE_H__
#define __BACKTRACE_H__
+#include <rtthread.h>
+
struct bt_frame
{
unsigned long fp;
@@ -20,4 +23,7 @@ struct bt_frame
void backtrace(unsigned long pc, unsigned long lr, unsigned long fp);
int rt_backtrace(void);
+int rt_backtrace_user_thread(rt_thread_t thread);
+int rt_backtrace_thread(rt_thread_t thread);
+
#endif /*__BACKTRACE_H__*/
diff --git a/libcpu/aarch64/common/context_gcc.S b/libcpu/aarch64/common/context_gcc.S
index d9dc2d1c93..e3487c9135 100644
--- a/libcpu/aarch64/common/context_gcc.S
+++ b/libcpu/aarch64/common/context_gcc.S
@@ -6,6 +6,7 @@
* Change Logs:
* Date Author Notes
* 2021-05-18 Jesven the first version
+ * 2023-06-24 WangXiaoyao Support backtrace for user thread
*/
#include "rtconfig.h"
@@ -375,13 +376,31 @@ rt_hw_context_switch_interrupt:
vector_fiq:
B .
+.macro SAVE_USER_CTX
+ MRS X1, SPSR_EL1
+ AND X1, X1, 0xf
+ CMP X1, XZR
+
+ BNE 1f
+ BL lwp_uthread_ctx_save
+ LDP X0, X1, [SP]
+1:
+.endm
+
.globl vector_irq
vector_irq:
SAVE_CONTEXT
STP X0, X1, [SP, #-0x10]! /* X0 is thread sp */
BL rt_interrupt_enter
+ LDP X0, X1, [SP]
+#ifdef RT_USING_LWP
+ SAVE_USER_CTX
+#endif
BL rt_hw_trap_irq
+#ifdef RT_USING_LWP
+ BL lwp_uthread_ctx_restore
+#endif
BL rt_interrupt_leave
LDP X0, X1, [SP], #0x10
@@ -515,7 +534,15 @@ vector_irq_exit:
START_POINT(vector_exception)
SAVE_CONTEXT
STP X0, X1, [SP, #-0x10]!
+#ifdef RT_USING_LWP
+ SAVE_USER_CTX
+#endif
+
BL rt_hw_trap_exception
+#ifdef RT_USING_LWP
+ BL lwp_uthread_ctx_restore
+#endif
+
LDP X0, X1, [SP], #0x10
MOV SP, X0
RESTORE_CONTEXT_WITHOUT_MMU_SWITCH
@@ -523,6 +550,9 @@ START_POINT_END(vector_exception)
START_POINT(vector_serror)
SAVE_CONTEXT
+#ifdef RT_USING_LWP
+ SAVE_USER_CTX
+#endif
STP X0, X1, [SP, #-0x10]!
BL rt_hw_trap_serror
b .
diff --git a/libcpu/aarch64/common/trap.c b/libcpu/aarch64/common/trap.c
index dd5468daf1..8e97a8b0aa 100644
--- a/libcpu/aarch64/common/trap.c
+++ b/libcpu/aarch64/common/trap.c
@@ -296,6 +296,19 @@ void rt_hw_trap_exception(struct rt_hw_exp_stack *regs)
#ifdef RT_USING_FINSH
list_thread();
#endif
+
+#ifdef RT_USING_LWP
+ {
+ rt_thread_t th;
+
+ th = rt_thread_self();
+ if (th && th->lwp)
+ {
+ rt_backtrace_user_thread(th);
+ }
+ }
+#endif
+
backtrace((unsigned long)regs->pc, (unsigned long)regs->x30, (unsigned long)regs->x29);
rt_hw_cpu_shutdown();
}
diff --git a/src/kservice.c b/src/kservice.c
index 9a8e89f4f2..b29497c765 100644
--- a/src/kservice.c
+++ b/src/kservice.c
@@ -75,6 +75,13 @@ rt_weak const char *rt_hw_cpu_arch(void)
return "unknown";
}
+rt_weak void rt_hw_cpu_reset(void)
+{
+ LOG_D("rt_hw_cpu_reset() doesn't support for this board."
+ "Please consider implementing rt_hw_cpu_reset() in another file.");
+ return ;
+}
+
static const char* rt_errno_strs[] =
{
"OK",