From 60a85ddc510514d1b2018fafb90a90cb4fdf591c Mon Sep 17 00:00:00 2001
From: songyanguang <345810377@qq.com>
Date: Fri, 24 Jan 2025 09:59:05 +0800
Subject: [PATCH] Fix conflict with the merge request to master
---
Ubiquitous/XiZi_AIoT/.config | 18 +
Ubiquitous/XiZi_AIoT/.gitignore | 1 +
Ubiquitous/XiZi_AIoT/Makefile | 9 +
Ubiquitous/XiZi_AIoT/README.md | 0
Ubiquitous/XiZi_AIoT/compiler.mk | 2 +-
Ubiquitous/XiZi_AIoT/hardkernel/arch/Makefile | 2 -
.../arm/armv7-a/cortex-a9/context_switch.S | 0
.../arch/arm/armv7-a/cortex-a9/core.h | 7 +
.../preboot_for_imx6q-sabrelite/boot.S | 2 +-
.../preboot_for_imx6q-sabrelite/cortexA9.S | 0
.../include/cortex_a9.h | 0
.../include/regsepit.h | 710 ++++++++++++++++++
.../preboot_for_zynq7000-zc702/cortexA9.S | 0
.../include/cortex_a9.h | 0
.../include/xil_assert.h | 0
.../include/xil_types.h | 0
.../arch/arm/armv8-a/cortex-a55/core.h | 9 +-
.../preboot_for_jh7110/include/registers.h | 110 +++
.../XiZi_AIoT/hardkernel/cache/L1/Makefile | 2 -
.../XiZi_AIoT/hardkernel/clock/Makefile | 4 +-
.../zynq7000-zc702/include/xscutimer.h | 0
.../zynq7000-zc702/include/xscutimer_hw.h | 0
.../cortex-a9/zynq7000-zc702/xscutimer.c | 0
.../cortex-a9/zynq7000-zc702/xscutimer_g.c | 0
.../zynq7000-zc702/xscutimer_selftest.c | 0
.../zynq7000-zc702/xscutimer_sinit.c | 0
.../XiZi_AIoT/hardkernel/hardkernel_init.c | 2 +-
Ubiquitous/XiZi_AIoT/hardkernel/intr/Makefile | 3 -
.../armv7-a/cortex-a9/gicv3/xil_exception.h | 0
.../arm/armv7-a/cortex-a9/gicv3/xscugic.c | 0
.../arm/armv7-a/cortex-a9/gicv3/xscugic.h | 0
.../arm/armv7-a/cortex-a9/gicv3/xscugic_g.c | 0
.../arm/armv7-a/cortex-a9/gicv3/xscugic_hw.c | 0
.../arm/armv7-a/cortex-a9/gicv3/xscugic_hw.h | 0
.../armv7-a/cortex-a9/gicv3/xscugic_intr.c | 0
.../armv7-a/cortex-a9/gicv3/xscugic_sinit.c | 0
.../arm/armv7-a/cortex-a9/gicv3/xstatus.h | 0
.../cortex-a9/imx6q-sabrelite/trap_common.c | 4 +-
.../cortex-a9/zynq7000-zc702/xil_assert.c | 0
Ubiquitous/XiZi_AIoT/hardkernel/mmu/Makefile | 2 -
.../cortex-a9/imx6q-sabrelite/memlayout.h | 7 +
.../mmu/arm/armv7-a/cortex-a9/include/mmu.h | 7 -
.../arm/armv8-a/cortex-a55/3568/memlayout.h | 4 +-
Ubiquitous/XiZi_AIoT/hardkernel/uart/Makefile | 3 -
.../uart_io_for_imx6q-sabrelite/imx_uart.c | 0
.../include/xil_io.h | 0
.../include/xpseudo_asm.h | 0
.../include/xpseudo_asm_gcc.h | 0
.../include/xreg_cortexa9.h | 0
.../uart_io_for_zynq7000-zc702/xil_io.c | 0
Ubiquitous/XiZi_AIoT/hardkernel/uart/printf.h | 3 +-
.../hardkernel/uart/uart_common_ope.c | 1 -
.../XiZi_AIoT/kernel_actracer/actracer.c | 56 +-
.../XiZi_AIoT/kernel_actracer/actracer.h | 31 +-
.../XiZi_AIoT/kernel_actracer/actracer_tag.h | 26 +
Ubiquitous/XiZi_AIoT/path_kernel.mk | 1 -
Ubiquitous/XiZi_AIoT/services/Makefile | 2 +-
Ubiquitous/XiZi_AIoT/services/app/.gitignore | 3 +
Ubiquitous/XiZi_AIoT/services/app/Makefile | 39 +-
.../XiZi_AIoT/services/app/pingpong_client.c | 154 ++++
.../XiZi_AIoT/services/app/pingpong_server.c | 39 +
.../XiZi_AIoT/services/app/pingpong_service.c | 26 +
.../XiZi_AIoT/services/app/pingpong_service.h | 20 +
.../XiZi_AIoT/services/app/simple_client.c | 0
.../XiZi_AIoT/services/app/simple_server.c | 0
.../services/app/test_context_user.c | 42 ++
.../XiZi_AIoT/services/app/test_sleep.c | 24 +
.../XiZi_AIoT/services/app/test_thread.c | 46 +-
.../services/boards/3568/arch_usyscall.c | 21 +
.../XiZi_AIoT/services/drivers/3568/Makefile | 2 +-
.../services/drivers/3568/hal/hal_base.c | 9 +-
.../services/drivers/3568/hal/hal_bsp.c | 30 +-
.../services/drivers/3568/hal/hal_cru.c | 357 ++++++++-
.../drivers/3568/hal/hal_cru_rk3568.c | 33 +
.../services/drivers/3568/hal/hal_gmac.c | 47 +-
.../services/drivers/3568/hal/hal_gpio.c | 71 +-
.../services/drivers/3568/hal/test_gmac.c | 101 +--
.../services/drivers/3568/include/hal_cru.h | 23 +
.../services/drivers/3568/include/hal_gmac.h | 14 +-
.../drivers/3568/include/hal_pinctrl.h | 525 ++++++++++++-
.../services/drivers/3568/include/soc.h | 13 +-
.../drivers/imx6q-sabrelite/clock/epit.c | 0
.../imx6q-sabrelite/enet/board_network.c | 0
.../drivers/imx6q-sabrelite/enet/enet.h | 0
.../drivers/imx6q-sabrelite/enet/enet_drv.c | 0
.../imx6q-sabrelite/enet/enet_private.h | 0
.../drivers/imx6q-sabrelite/enet/enet_test.c | 0
.../imx6q-sabrelite/include/soc_memory_map.h | 0
.../XiZi_AIoT/services/fs/fs_server/fs.c | 6 +-
.../services/fs/fs_server/fs_server.c | 4 +-
.../services/fs/fs_server/include/fs.h | 8 +-
.../XiZi_AIoT/services/lib/ipc/libipc.c | 6 +-
.../XiZi_AIoT/services/lib/ipc/libipc.h | 9 +-
.../XiZi_AIoT/services/lib/ipc/session.h | 2 +-
.../services/lib/usyscall/usyscall.c | 41 +-
.../services/lib/usyscall/usyscall.h | 27 +-
.../services/semaphore/semaphore_server.c | 39 +-
.../services/shell/letter-shell/shell.c | 5 +
.../shell/letter-shell/shell_cmd_list.c | 3 +
.../services/tools/hosttools/xsconfig.sh | 0
.../XiZi_AIoT/services/tools/mkfs/.gitignore | 1 +
.../XiZi_AIoT/services/tools/mkfs/Makefile | 0
.../XiZi_AIoT/services/tools/mkfs/mkfs.c | 0
.../XiZi_AIoT/services/tools/mkfs/mkfs.h | 4 +-
Ubiquitous/XiZi_AIoT/softkernel/Makefile | 2 +-
.../XiZi_AIoT/softkernel/include/assert.h | 2 +
.../XiZi_AIoT/softkernel/include/bitmap64.h | 13 +-
.../XiZi_AIoT/softkernel/include/buddy.h | 4 +-
.../XiZi_AIoT/softkernel/include/execelf.h | 0
Ubiquitous/XiZi_AIoT/softkernel/include/ipc.h | 11 +-
.../XiZi_AIoT/softkernel/include/kalloc.h | 13 +-
.../XiZi_AIoT/softkernel/include/ksemaphore.h | 27 +-
Ubiquitous/XiZi_AIoT/softkernel/include/log.h | 15 +-
.../XiZi_AIoT/softkernel/include/memspace.h | 10 +-
.../softkernel/include/object_allocator.h | 5 +-
.../XiZi_AIoT/softkernel/include/pagetable.h | 5 +-
.../XiZi_AIoT/softkernel/include/queue.h | 22 +
.../XiZi_AIoT/softkernel/include/rbtree.h | 50 ++
.../softkernel/include/schedule_algo.h | 36 +
.../XiZi_AIoT/softkernel/include/scheduler.h | 89 ++-
.../XiZi_AIoT/softkernel/include/share_page.h | 28 +-
.../XiZi_AIoT/softkernel/include/syscall.h | 18 +
.../XiZi_AIoT/softkernel/include/task.h | 56 +-
.../softkernel/init/softkernel_init.c | 6 +-
Ubiquitous/XiZi_AIoT/softkernel/main.c | 8 +
.../XiZi_AIoT/softkernel/memory/buddy.c | 9 +-
.../XiZi_AIoT/softkernel/memory/kalloc.c | 55 +-
.../softkernel/memory/object_allocator.c | 12 +-
.../XiZi_AIoT/softkernel/memory/pagetable.c | 18 +-
.../softkernel/memory/pagetable_riscv.c | 18 +-
.../XiZi_AIoT/softkernel/memory/share_page.c | 62 +-
.../XiZi_AIoT/softkernel/syscall/Makefile | 4 +-
.../softkernel/syscall/sys_close_session.c | 59 +-
.../XiZi_AIoT/softkernel/syscall/sys_exit.c | 8 +-
.../XiZi_AIoT/softkernel/syscall/sys_kill.c | 62 +-
.../XiZi_AIoT/softkernel/syscall/sys_mmap.c | 95 ++-
.../softkernel/syscall/sys_poll_session.c | 101 ++-
.../syscall/sys_register_as_server.c | 2 -
.../softkernel/syscall/sys_register_irq.c | 16 +-
.../softkernel/syscall/sys_semaphore.c | 2 +-
.../XiZi_AIoT/softkernel/syscall/sys_sleep.c | 43 ++
.../XiZi_AIoT/softkernel/syscall/sys_spawn.c | 14 +-
.../XiZi_AIoT/softkernel/syscall/sys_state.c | 90 +--
.../XiZi_AIoT/softkernel/syscall/sys_thread.c | 12 +-
.../softkernel/syscall/sys_wait_session.c | 66 ++
.../XiZi_AIoT/softkernel/syscall/sys_yield.c | 24 +-
.../XiZi_AIoT/softkernel/syscall/syscall.c | 8 +-
.../XiZi_AIoT/softkernel/task/memspace.c | 45 +-
.../XiZi_AIoT/softkernel/task/schedule.c | 167 ++--
.../XiZi_AIoT/softkernel/task/semaphore.c | 94 ++-
Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 417 +++++-----
.../XiZi_AIoT/softkernel/tools/Makefile | 4 +
Ubiquitous/XiZi_AIoT/softkernel/tools/queue.c | 79 ++
.../XiZi_AIoT/softkernel/tools/rbtree.c | 484 ++++++++++++
.../XiZi_AIoT/softkernel/trap/abort_handler.c | 2 -
.../softkernel/trap/clock_irq_handler.c | 29 +-
.../softkernel/trap/default_irq_handler.c | 4 +-
.../softkernel/trap/software_irq_handler.c | 10 +-
158 files changed, 4437 insertions(+), 920 deletions(-)
create mode 100644 Ubiquitous/XiZi_AIoT/.config
create mode 100644 Ubiquitous/XiZi_AIoT/.gitignore
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/Makefile
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/README.md
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/context_switch.S
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/cortexA9.S
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/include/cortex_a9.h
create mode 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/include/regsepit.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/cortexA9.S
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/include/cortex_a9.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/include/xil_assert.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/include/xil_types.h
create mode 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/include/registers.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/include/xscutimer.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/include/xscutimer_hw.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer_g.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer_selftest.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer_sinit.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xil_exception.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_g.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_hw.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_hw.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_intr.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_sinit.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xstatus.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/xil_assert.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_imx6q-sabrelite/imx_uart.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xil_io.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xpseudo_asm.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xpseudo_asm_gcc.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xreg_cortexa9.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/xil_io.c
create mode 100644 Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_tag.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/path_kernel.mk
create mode 100644 Ubiquitous/XiZi_AIoT/services/app/.gitignore
create mode 100644 Ubiquitous/XiZi_AIoT/services/app/pingpong_client.c
create mode 100644 Ubiquitous/XiZi_AIoT/services/app/pingpong_server.c
create mode 100644 Ubiquitous/XiZi_AIoT/services/app/pingpong_service.c
create mode 100644 Ubiquitous/XiZi_AIoT/services/app/pingpong_service.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/app/simple_client.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/app/simple_server.c
create mode 100644 Ubiquitous/XiZi_AIoT/services/app/test_context_user.c
create mode 100644 Ubiquitous/XiZi_AIoT/services/app/test_sleep.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/clock/epit.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/board_network.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet_drv.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet_private.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet_test.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/include/soc_memory_map.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/tools/hosttools/xsconfig.sh
create mode 100644 Ubiquitous/XiZi_AIoT/services/tools/mkfs/.gitignore
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/tools/mkfs/Makefile
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/tools/mkfs/mkfs.c
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/services/tools/mkfs/mkfs.h
mode change 100755 => 100644 Ubiquitous/XiZi_AIoT/softkernel/include/execelf.h
create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/include/queue.h
create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/include/rbtree.h
create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/include/schedule_algo.h
create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_sleep.c
create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_wait_session.c
create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/tools/Makefile
create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/tools/queue.c
create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/tools/rbtree.c
diff --git a/Ubiquitous/XiZi_AIoT/.config b/Ubiquitous/XiZi_AIoT/.config
new file mode 100644
index 000000000..a40a1d2b4
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/.config
@@ -0,0 +1,18 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# XiZi_AIoT Project Configuration
+#
+CONFIG_BOARD_IMX6Q_SABRELITE=y
+CONFIG_ARCH_ARM=y
+
+#
+# imx6q sabrelite feature
+#
+
+#
+# Lib
+#
+CONFIG_LIB=y
+CONFIG_LIB_POSIX=y
+CONFIG_LIB_NEWLIB=y
+# CONFIG_LIB_MUSLLIB is not set
diff --git a/Ubiquitous/XiZi_AIoT/.gitignore b/Ubiquitous/XiZi_AIoT/.gitignore
new file mode 100644
index 000000000..c795b054e
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/.gitignore
@@ -0,0 +1 @@
+build
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/Makefile b/Ubiquitous/XiZi_AIoT/Makefile
old mode 100755
new mode 100644
index 0f58c8fda..c797af470
--- a/Ubiquitous/XiZi_AIoT/Makefile
+++ b/Ubiquitous/XiZi_AIoT/Makefile
@@ -145,3 +145,12 @@ distclean:
@rm -f .config*
@rm -f $(KERNEL_ROOT)/lib/musllib/libmusl.a
@rm -f $(KERNEL_ROOT)/board/*/.config
+
+
+# Run qemu with config discribed in README.md.
+.PHONY: qemu-default
+qemu-default:
+ qemu-system-arm -M sabrelite -m 1G -smp 4 -cpu cortex-a9 \
+ -display none -serial null -serial stdio \
+ -kernel ./build/XiZi-imx6q-sabrelite.elf
+
diff --git a/Ubiquitous/XiZi_AIoT/README.md b/Ubiquitous/XiZi_AIoT/README.md
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/compiler.mk b/Ubiquitous/XiZi_AIoT/compiler.mk
index 053cc1405..335dbbac6 100644
--- a/Ubiquitous/XiZi_AIoT/compiler.mk
+++ b/Ubiquitous/XiZi_AIoT/compiler.mk
@@ -34,7 +34,7 @@ $(eval LOCALC := $(addprefix $(BUILD_DIR)/,$(COBJ))) \
$(eval OBJS += $(LOCALC)) \
$(if $(strip $(LOCALC)),$(eval $(LOCALC): $(1)
@if [ ! -d $$(@D) ]; then mkdir -p $$(@D); fi
- @echo cc $$<
+ @echo cc $(subst $(KERNEL_ROOT)/,,$$<)
@/bin/echo -n $(dir $(LOCALC)) >>$(KERNEL_ROOT)/build/make.dep
@($(CROSS_COMPILE)gcc -MM $$(CFLAGS) -c $$<) >>$(KERNEL_ROOT)/build/make.dep
@$(CROSS_COMPILE)gcc $$(CFLAGS) -c $$< -o $$@))
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/arch/Makefile
index 4972e6661..75c9775cb 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/Makefile
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/Makefile
@@ -1,6 +1,4 @@
-ifneq ($(findstring $(BOARD), 3568 imx6q-sabrelite zynq7000-zc702), )
SRC_DIR := arm
-endif
ifneq ($(findstring $(BOARD), jh7110), )
SRC_DIR := riscv
endif
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/context_switch.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/context_switch.S
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h
index 01c5623bf..daed03bd4 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h
@@ -76,6 +76,13 @@ Modification:
#define NR_CPU 4
+static inline uint64_t arch_current_tick()
+{
+ uint32_t tick = 0;
+ __asm__ __volatile__("MRC p15, 0, %0, c9, c13, 0" : "=r"(tick)); // %0 应该是输出操作数
+ return (uint64_t)tick;
+}
+
__attribute__((always_inline, optimize("O0"))) static inline uint32_t user_mode()
{
uint32_t val;
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/boot.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/boot.S
index 30e353d3b..ce2b4bcf6 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/boot.S
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/boot.S
@@ -77,7 +77,7 @@ _boot_start:
mul r3, r2, r1
sub r0, r0, r3
- msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT
+ msr CPSR_c, #ARM_MODE_SVC | I_BIT
mov sp, r0
sub r0, r0, r1
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/cortexA9.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/cortexA9.S
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/include/cortex_a9.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/include/cortex_a9.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/include/regsepit.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/include/regsepit.h
new file mode 100644
index 000000000..c57ac13d5
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/include/regsepit.h
@@ -0,0 +1,710 @@
+/*
+ * Copyright (c) 2012, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FREESCALE "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 FREESCALE 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.
+ */
+/*
+ * WARNING! DO NOT EDIT THIS FILE DIRECTLY!
+ *
+ * This file was generated automatically and any changes may be lost.
+ */
+#ifndef __HW_EPIT_REGISTERS_H__
+#define __HW_EPIT_REGISTERS_H__
+
+#include "regs.h"
+#include "soc_memory_map.h"
+
+/*
+ * i.MX6SL EPIT
+ *
+ * EPIT
+ *
+ * Registers defined in this header file:
+ * - HW_EPIT_CR - Control register
+ * - HW_EPIT_SR - Status register
+ * - HW_EPIT_LR - Load register
+ * - HW_EPIT_CMPR - Compare register
+ * - HW_EPIT_CNR - Counter register
+ *
+ * - hw_epit_t - Struct containing all module registers.
+ */
+
+//! @name Module base addresses
+//@{
+#ifndef REGS_EPIT_BASE
+#define HW_EPIT_INSTANCE_COUNT (2) //!< Number of instances of the EPIT module.
+#define HW_EPIT1 (1) //!< Instance number for EPIT1.
+#define HW_EPIT2 (2) //!< Instance number for EPIT2.
+#define REGS_EPIT1_BASE USERLAND_MMIO_P2V(0x020d0000) //!< Base address for EPIT instance number 1.
+#define REGS_EPIT2_BASE USERLAND_MMIO_P2V(0x020d4000) //!< Base address for EPIT instance number 2.
+
+//! @brief Get the base address of EPIT by instance number.
+//! @param x EPIT instance number, from 1 through 2.
+#define REGS_EPIT_BASE(x) ((x) == HW_EPIT1 ? REGS_EPIT1_BASE : (x) == HW_EPIT2 ? REGS_EPIT2_BASE \
+ : 0x00d00000)
+
+//! @brief Get the instance number given a base address.
+//! @param b Base address for an instance of EPIT.
+#define REGS_EPIT_INSTANCE(b) ((b) == REGS_EPIT1_BASE ? HW_EPIT1 : (b) == REGS_EPIT2_BASE ? HW_EPIT2 \
+ : 0)
+#endif
+//@}
+
+//-------------------------------------------------------------------------------------------
+// HW_EPIT_CR - Control register
+//-------------------------------------------------------------------------------------------
+
+#ifndef __LANGUAGE_ASM__
+/*!
+ * @brief HW_EPIT_CR - Control register (RW)
+ *
+ * Reset value: 0x00000000
+ *
+ * The EPIT control register (EPIT_CR) is used to configure the operating settings of the EPIT. It
+ * contains the clock division prescaler value and also the interrupt enable bit. Additionally, it
+ * contains other control bits which are described below. Peripheral Bus Write access to EPIT
+ * Control Register (EPIT_CR) results in one cycle of the wait state, while other valid peripheral
+ * bus accesses are with 0 wait state.
+ */
+typedef union _hw_epit_cr {
+ reg32_t U;
+ struct _hw_epit_cr_bitfields {
+ unsigned EN : 1; //!< [0] This bit enables the EPIT.
+ unsigned ENMOD : 1; //!< [1] EPIT enable mode.
+ unsigned OCIEN : 1; //!< [2] Output compare interrupt enable.
+ unsigned RLD : 1; //!< [3] Counter reload control.
+ unsigned PRESCALAR : 12; //!< [15:4] Counter clock prescaler value.
+ unsigned SWR : 1; //!< [16] Software reset.
+ unsigned IOVW : 1; //!< [17] EPIT counter overwrite enable.
+ unsigned DBGEN : 1; //!< [18] This bit is used to keep the EPIT functional in debug mode.
+ unsigned WAITEN : 1; //!< [19] This read/write control bit enables the operation of the EPIT during wait mode.
+ unsigned RESERVED0 : 1; //!< [20] Reserved.
+ unsigned STOPEN : 1; //!< [21] EPIT stop mode enable.
+ unsigned OM : 2; //!< [23:22] EPIT output mode.This bit field determines the mode of EPIT output on the output pin.
+ unsigned CLKSRC : 2; //!< [25:24] Select clock source
+ unsigned RESERVED1 : 6; //!< [31:26] Reserved.
+ } B;
+} hw_epit_cr_t;
+#endif
+
+/*!
+ * @name Constants and macros for entire EPIT_CR register
+ */
+//@{
+#define HW_EPIT_CR_ADDR(x) (REGS_EPIT_BASE(x) + 0x0)
+
+#ifndef __LANGUAGE_ASM__
+#define HW_EPIT_CR(x) (*(volatile hw_epit_cr_t*)HW_EPIT_CR_ADDR(x))
+#define HW_EPIT_CR_RD(x) (HW_EPIT_CR(x).U)
+#define HW_EPIT_CR_WR(x, v) (HW_EPIT_CR(x).U = (v))
+#define HW_EPIT_CR_SET(x, v) (HW_EPIT_CR_WR(x, HW_EPIT_CR_RD(x) | (v)))
+#define HW_EPIT_CR_CLR(x, v) (HW_EPIT_CR_WR(x, HW_EPIT_CR_RD(x) & ~(v)))
+#define HW_EPIT_CR_TOG(x, v) (HW_EPIT_CR_WR(x, HW_EPIT_CR_RD(x) ^ (v)))
+#endif
+//@}
+
+/*
+ * constants & macros for individual EPIT_CR bitfields
+ */
+
+/*! @name Register EPIT_CR, field EN[0] (RW)
+ *
+ * This bit enables the EPIT. EPIT counter and prescaler value when EPIT is enabled (EN = 1), is
+ * dependent upon ENMOD and RLD bit as described for ENMOD bit. It is recommended that all registers
+ * be properly programmed before setting this bit. This bit is reset by a hardware reset. A software
+ * reset does not affect this bit.
+ *
+ * Values:
+ * - 0 - EPIT is disabled
+ * - 1 - EPIT is enabled
+ */
+//@{
+#define BP_EPIT_CR_EN (0) //!< Bit position for EPIT_CR_EN.
+#define BM_EPIT_CR_EN (0x00000001) //!< Bit mask for EPIT_CR_EN.
+
+//! @brief Get value of EPIT_CR_EN from a register value.
+#define BG_EPIT_CR_EN(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_EN) >> BP_EPIT_CR_EN)
+
+//! @brief Format value for bitfield EPIT_CR_EN.
+#define BF_EPIT_CR_EN(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_EN) & BM_EPIT_CR_EN)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the EN field to a new value.
+#define BW_EPIT_CR_EN(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_EN) | BF_EPIT_CR_EN(v)))
+#endif
+//@}
+
+/*! @name Register EPIT_CR, field ENMOD[1] (RW)
+ *
+ * EPIT enable mode. When EPIT is disabled (EN=0), both main counter and prescaler counter freeze
+ * their count at current count values. ENMOD bit is a r/w bit that determines the counter value
+ * when the EPIT is enabled again by setting EN bit. If ENMOD bit is set, then main counter is
+ * loaded with the load value (If RLD=1)/ 0xFFFF_FFFF (If RLD=0) and prescaler counter is reset,
+ * when EPIT is enabled (EN=1). If ENMOD is programmed to 0 then both main counter and prescaler
+ * counter restart counting from their frozen values when EPIT is enabled (EN=1). If EPIT is
+ * programmed to be disabled in a low-power mode (STOP/WAIT/DEBUG), then both the main counter and
+ * the prescaler counter freeze at their current count values when EPIT enters low-power mode. When
+ * EPIT exits the low-power mode, both main counter and prescaler counter start counting from their
+ * frozen values irrespective of the ENMOD bit. This bit is reset by a hardware reset. A software
+ * reset does not affect this bit.
+ *
+ * Values:
+ * - 0 - Counter starts counting from the value it had when it was disabled.
+ * - 1 - Counter starts count from load value (RLD=1) or 0xFFFF_FFFF (If RLD=0)
+ */
+//@{
+#define BP_EPIT_CR_ENMOD (1) //!< Bit position for EPIT_CR_ENMOD.
+#define BM_EPIT_CR_ENMOD (0x00000002) //!< Bit mask for EPIT_CR_ENMOD.
+
+//! @brief Get value of EPIT_CR_ENMOD from a register value.
+#define BG_EPIT_CR_ENMOD(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_ENMOD) >> BP_EPIT_CR_ENMOD)
+
+//! @brief Format value for bitfield EPIT_CR_ENMOD.
+#define BF_EPIT_CR_ENMOD(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_ENMOD) & BM_EPIT_CR_ENMOD)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the ENMOD field to a new value.
+#define BW_EPIT_CR_ENMOD(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_ENMOD) | BF_EPIT_CR_ENMOD(v)))
+#endif
+//@}
+
+/*! @name Register EPIT_CR, field OCIEN[2] (RW)
+ *
+ * Output compare interrupt enable. This bit enables the generation of interrupt on occurrence of
+ * compare event.
+ *
+ * Values:
+ * - 0 - Compare interrupt disabled
+ * - 1 - Compare interrupt enabled
+ */
+//@{
+#define BP_EPIT_CR_OCIEN (2) //!< Bit position for EPIT_CR_OCIEN.
+#define BM_EPIT_CR_OCIEN (0x00000004) //!< Bit mask for EPIT_CR_OCIEN.
+
+//! @brief Get value of EPIT_CR_OCIEN from a register value.
+#define BG_EPIT_CR_OCIEN(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_OCIEN) >> BP_EPIT_CR_OCIEN)
+
+//! @brief Format value for bitfield EPIT_CR_OCIEN.
+#define BF_EPIT_CR_OCIEN(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_OCIEN) & BM_EPIT_CR_OCIEN)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the OCIEN field to a new value.
+#define BW_EPIT_CR_OCIEN(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_OCIEN) | BF_EPIT_CR_OCIEN(v)))
+#endif
+//@}
+
+/*! @name Register EPIT_CR, field RLD[3] (RW)
+ *
+ * Counter reload control. This bit is cleared by hardware reset. It decides the counter
+ * functionality, whether to run in free-running mode or set-and-forget mode.
+ *
+ * Values:
+ * - 0 - When the counter reaches zero it rolls over to 0xFFFF_FFFF (free-running mode)
+ * - 1 - When the counter reaches zero it reloads from the modulus register (set-and-forget mode)
+ */
+//@{
+#define BP_EPIT_CR_RLD (3) //!< Bit position for EPIT_CR_RLD.
+#define BM_EPIT_CR_RLD (0x00000008) //!< Bit mask for EPIT_CR_RLD.
+
+//! @brief Get value of EPIT_CR_RLD from a register value.
+#define BG_EPIT_CR_RLD(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_RLD) >> BP_EPIT_CR_RLD)
+
+//! @brief Format value for bitfield EPIT_CR_RLD.
+#define BF_EPIT_CR_RLD(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_RLD) & BM_EPIT_CR_RLD)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the RLD field to a new value.
+#define BW_EPIT_CR_RLD(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_RLD) | BF_EPIT_CR_RLD(v)))
+#endif
+//@}
+
+/*! @name Register EPIT_CR, field PRESCALAR[15:4] (RW)
+ *
+ * Counter clock prescaler value. This bit field determines the prescaler value by which the clock
+ * is divided before it goes to the counter
+ *
+ * Values:
+ * - 0x000 - Divide by 1
+ * - 0x001 - Divide by 2...
+ * - 0xFFF - Divide by 4096
+ */
+//@{
+#define BP_EPIT_CR_PRESCALAR (4) //!< Bit position for EPIT_CR_PRESCALAR.
+#define BM_EPIT_CR_PRESCALAR (0x0000fff0) //!< Bit mask for EPIT_CR_PRESCALAR.
+
+//! @brief Get value of EPIT_CR_PRESCALAR from a register value.
+#define BG_EPIT_CR_PRESCALAR(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_PRESCALAR) >> BP_EPIT_CR_PRESCALAR)
+
+//! @brief Format value for bitfield EPIT_CR_PRESCALAR.
+#define BF_EPIT_CR_PRESCALAR(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_PRESCALAR) & BM_EPIT_CR_PRESCALAR)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the PRESCALAR field to a new value.
+#define BW_EPIT_CR_PRESCALAR(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_PRESCALAR) | BF_EPIT_CR_PRESCALAR(v)))
+#endif
+//@}
+
+/*! @name Register EPIT_CR, field SWR[16] (RW)
+ *
+ * Software reset. The EPIT is reset when this bit is set to 1. It is a self clearing bit. This bit
+ * is set when the block is in reset state and is cleared when the reset procedure is over. Setting
+ * this bit resets all the registers to their reset values, except for the EN, ENMOD, STOPEN, WAITEN
+ * and DBGEN bits in this control register
+ *
+ * Values:
+ * - 0 - EPIT is out of reset
+ * - 1 - EPIT is undergoing reset
+ */
+//@{
+#define BP_EPIT_CR_SWR (16) //!< Bit position for EPIT_CR_SWR.
+#define BM_EPIT_CR_SWR (0x00010000) //!< Bit mask for EPIT_CR_SWR.
+
+//! @brief Get value of EPIT_CR_SWR from a register value.
+#define BG_EPIT_CR_SWR(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_SWR) >> BP_EPIT_CR_SWR)
+
+//! @brief Format value for bitfield EPIT_CR_SWR.
+#define BF_EPIT_CR_SWR(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_SWR) & BM_EPIT_CR_SWR)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the SWR field to a new value.
+#define BW_EPIT_CR_SWR(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_SWR) | BF_EPIT_CR_SWR(v)))
+#endif
+//@}
+
+/*! @name Register EPIT_CR, field IOVW[17] (RW)
+ *
+ * EPIT counter overwrite enable. This bit controls the counter data when the modulus register is
+ * written. When this bit is set, all writes to the load register overwrites the counter contents
+ * and the counter starts subsequently counting down from the programmed value.
+ *
+ * Values:
+ * - 0 - Write to load register does not result in counter value being overwritten.
+ * - 1 - Write to load register results in immediate overwriting of counter value.
+ */
+//@{
+#define BP_EPIT_CR_IOVW (17) //!< Bit position for EPIT_CR_IOVW.
+#define BM_EPIT_CR_IOVW (0x00020000) //!< Bit mask for EPIT_CR_IOVW.
+
+//! @brief Get value of EPIT_CR_IOVW from a register value.
+#define BG_EPIT_CR_IOVW(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_IOVW) >> BP_EPIT_CR_IOVW)
+
+//! @brief Format value for bitfield EPIT_CR_IOVW.
+#define BF_EPIT_CR_IOVW(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_IOVW) & BM_EPIT_CR_IOVW)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the IOVW field to a new value.
+#define BW_EPIT_CR_IOVW(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_IOVW) | BF_EPIT_CR_IOVW(v)))
+#endif
+//@}
+
+/*! @name Register EPIT_CR, field DBGEN[18] (RW)
+ *
+ * This bit is used to keep the EPIT functional in debug mode. When this bit is cleared, the input
+ * clock is gated off in debug mode.This bit is reset by hardware reset. A software reset does not
+ * affect this bit.
+ *
+ * Values:
+ * - 0 - Inactive in debug mode
+ * - 1 - Active in debug mode
+ */
+//@{
+#define BP_EPIT_CR_DBGEN (18) //!< Bit position for EPIT_CR_DBGEN.
+#define BM_EPIT_CR_DBGEN (0x00040000) //!< Bit mask for EPIT_CR_DBGEN.
+
+//! @brief Get value of EPIT_CR_DBGEN from a register value.
+#define BG_EPIT_CR_DBGEN(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_DBGEN) >> BP_EPIT_CR_DBGEN)
+
+//! @brief Format value for bitfield EPIT_CR_DBGEN.
+#define BF_EPIT_CR_DBGEN(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_DBGEN) & BM_EPIT_CR_DBGEN)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the DBGEN field to a new value.
+#define BW_EPIT_CR_DBGEN(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_DBGEN) | BF_EPIT_CR_DBGEN(v)))
+#endif
+//@}
+
+/*! @name Register EPIT_CR, field WAITEN[19] (RW)
+ *
+ * This read/write control bit enables the operation of the EPIT during wait mode. This bit is reset
+ * by a hardware reset. A software reset does not affect this bit.
+ *
+ * Values:
+ * - 0 - EPIT is disabled in wait mode
+ * - 1 - EPIT is enabled in wait mode
+ */
+//@{
+#define BP_EPIT_CR_WAITEN (19) //!< Bit position for EPIT_CR_WAITEN.
+#define BM_EPIT_CR_WAITEN (0x00080000) //!< Bit mask for EPIT_CR_WAITEN.
+
+//! @brief Get value of EPIT_CR_WAITEN from a register value.
+#define BG_EPIT_CR_WAITEN(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_WAITEN) >> BP_EPIT_CR_WAITEN)
+
+//! @brief Format value for bitfield EPIT_CR_WAITEN.
+#define BF_EPIT_CR_WAITEN(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_WAITEN) & BM_EPIT_CR_WAITEN)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the WAITEN field to a new value.
+#define BW_EPIT_CR_WAITEN(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_WAITEN) | BF_EPIT_CR_WAITEN(v)))
+#endif
+//@}
+
+/*! @name Register EPIT_CR, field STOPEN[21] (RW)
+ *
+ * EPIT stop mode enable. This read/write control bit enables the operation of the EPIT during stop
+ * mode. This bit is reset by a hardware reset and unaffected by software reset.
+ *
+ * Values:
+ * - 0 - EPIT is disabled in stop mode
+ * - 1 - EPIT is enabled in stop mode
+ */
+//@{
+#define BP_EPIT_CR_STOPEN (21) //!< Bit position for EPIT_CR_STOPEN.
+#define BM_EPIT_CR_STOPEN (0x00200000) //!< Bit mask for EPIT_CR_STOPEN.
+
+//! @brief Get value of EPIT_CR_STOPEN from a register value.
+#define BG_EPIT_CR_STOPEN(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_STOPEN) >> BP_EPIT_CR_STOPEN)
+
+//! @brief Format value for bitfield EPIT_CR_STOPEN.
+#define BF_EPIT_CR_STOPEN(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_STOPEN) & BM_EPIT_CR_STOPEN)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the STOPEN field to a new value.
+#define BW_EPIT_CR_STOPEN(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_STOPEN) | BF_EPIT_CR_STOPEN(v)))
+#endif
+//@}
+
+/*! @name Register EPIT_CR, field OM[23:22] (RW)
+ *
+ * EPIT output mode.This bit field determines the mode of EPIT output on the output pin.
+ *
+ * Values:
+ * - 00 - EPIT output is disconnected from pad
+ * - 01 - Toggle output pin
+ * - 10 - Clear output pin
+ * - 11 - Set output pin
+ */
+//@{
+#define BP_EPIT_CR_OM (22) //!< Bit position for EPIT_CR_OM.
+#define BM_EPIT_CR_OM (0x00c00000) //!< Bit mask for EPIT_CR_OM.
+
+//! @brief Get value of EPIT_CR_OM from a register value.
+#define BG_EPIT_CR_OM(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_OM) >> BP_EPIT_CR_OM)
+
+//! @brief Format value for bitfield EPIT_CR_OM.
+#define BF_EPIT_CR_OM(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_OM) & BM_EPIT_CR_OM)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the OM field to a new value.
+#define BW_EPIT_CR_OM(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_OM) | BF_EPIT_CR_OM(v)))
+#endif
+//@}
+
+/*! @name Register EPIT_CR, field CLKSRC[25:24] (RW)
+ *
+ * Select clock source These bits determine which clock input is to be selected for running the
+ * counter. This field value should only be changed when the EPIT is disabled by clearing the EN bit
+ * in this register. For other programming requirements while changing clock source, refer to .
+ *
+ * Values:
+ * - 00 - Clock is off
+ * - 01 - Peripheral clock
+ * - 10 - High-frequency reference clock
+ * - 11 - Low-frequency reference clock
+ */
+//@{
+#define BP_EPIT_CR_CLKSRC (24) //!< Bit position for EPIT_CR_CLKSRC.
+#define BM_EPIT_CR_CLKSRC (0x03000000) //!< Bit mask for EPIT_CR_CLKSRC.
+
+//! @brief Get value of EPIT_CR_CLKSRC from a register value.
+#define BG_EPIT_CR_CLKSRC(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CR_CLKSRC) >> BP_EPIT_CR_CLKSRC)
+
+//! @brief Format value for bitfield EPIT_CR_CLKSRC.
+#define BF_EPIT_CR_CLKSRC(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CR_CLKSRC) & BM_EPIT_CR_CLKSRC)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the CLKSRC field to a new value.
+#define BW_EPIT_CR_CLKSRC(x, v) (HW_EPIT_CR_WR(x, (HW_EPIT_CR_RD(x) & ~BM_EPIT_CR_CLKSRC) | BF_EPIT_CR_CLKSRC(v)))
+#endif
+//@}
+
+//-------------------------------------------------------------------------------------------
+// HW_EPIT_SR - Status register
+//-------------------------------------------------------------------------------------------
+
+#ifndef __LANGUAGE_ASM__
+/*!
+ * @brief HW_EPIT_SR - Status register (RW)
+ *
+ * Reset value: 0x00000000
+ *
+ * The EPIT status register (EPIT_SR) has a single status bit for the output compare event. The bit
+ * is a write 1 to clear bit.
+ */
+typedef union _hw_epit_sr {
+ reg32_t U;
+ struct _hw_epit_sr_bitfields {
+ unsigned OCIF : 1; //!< [0] Output compare interrupt flag.
+ unsigned RESERVED0 : 31; //!< [31:1] Reserved.
+ } B;
+} hw_epit_sr_t;
+#endif
+
+/*!
+ * @name Constants and macros for entire EPIT_SR register
+ */
+//@{
+#define HW_EPIT_SR_ADDR(x) (REGS_EPIT_BASE(x) + 0x4)
+
+#ifndef __LANGUAGE_ASM__
+#define HW_EPIT_SR(x) (*(volatile hw_epit_sr_t*)HW_EPIT_SR_ADDR(x))
+#define HW_EPIT_SR_RD(x) (HW_EPIT_SR(x).U)
+#define HW_EPIT_SR_WR(x, v) (HW_EPIT_SR(x).U = (v))
+#define HW_EPIT_SR_SET(x, v) (HW_EPIT_SR_WR(x, HW_EPIT_SR_RD(x) | (v)))
+#define HW_EPIT_SR_CLR(x, v) (HW_EPIT_SR_WR(x, HW_EPIT_SR_RD(x) & ~(v)))
+#define HW_EPIT_SR_TOG(x, v) (HW_EPIT_SR_WR(x, HW_EPIT_SR_RD(x) ^ (v)))
+#endif
+//@}
+
+/*
+ * constants & macros for individual EPIT_SR bitfields
+ */
+
+/*! @name Register EPIT_SR, field OCIF[0] (W1C)
+ *
+ * Output compare interrupt flag. This bit is the interrupt flag that is set when the content of
+ * counter equals the content of the compare register (EPIT_CMPR). The bit is a write 1 to clear
+ * bit.
+ *
+ * Values:
+ * - 0 - Compare event has not occurred
+ * - 1 - Compare event occurred
+ */
+//@{
+#define BP_EPIT_SR_OCIF (0) //!< Bit position for EPIT_SR_OCIF.
+#define BM_EPIT_SR_OCIF (0x00000001) //!< Bit mask for EPIT_SR_OCIF.
+
+//! @brief Get value of EPIT_SR_OCIF from a register value.
+#define BG_EPIT_SR_OCIF(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_SR_OCIF) >> BP_EPIT_SR_OCIF)
+
+//! @brief Format value for bitfield EPIT_SR_OCIF.
+#define BF_EPIT_SR_OCIF(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_SR_OCIF) & BM_EPIT_SR_OCIF)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the OCIF field to a new value.
+#define BW_EPIT_SR_OCIF(x, v) (HW_EPIT_SR_WR(x, (HW_EPIT_SR_RD(x) & ~BM_EPIT_SR_OCIF) | BF_EPIT_SR_OCIF(v)))
+#endif
+//@}
+
+//-------------------------------------------------------------------------------------------
+// HW_EPIT_LR - Load register
+//-------------------------------------------------------------------------------------------
+
+#ifndef __LANGUAGE_ASM__
+/*!
+ * @brief HW_EPIT_LR - Load register (RW)
+ *
+ * Reset value: 0xffffffff
+ *
+ * The EPIT load register (EPIT_LR) contains the value that is to be loaded into the counter when
+ * EPIT counter reaches zero if the RLD bit in EPIT_CR is set. If the IOVW bit in the EPIT_CR is set
+ * then a write to this register overwrites the value of the EPIT counter register in addition to
+ * updating this registers value. This overwrite feature is active even if the RLD bit is not set.
+ */
+typedef union _hw_epit_lr {
+ reg32_t U;
+ struct _hw_epit_lr_bitfields {
+ unsigned LOAD : 32; //!< [31:0] Load value.
+ } B;
+} hw_epit_lr_t;
+#endif
+
+/*!
+ * @name Constants and macros for entire EPIT_LR register
+ */
+//@{
+#define HW_EPIT_LR_ADDR(x) (REGS_EPIT_BASE(x) + 0x8)
+
+#ifndef __LANGUAGE_ASM__
+#define HW_EPIT_LR(x) (*(volatile hw_epit_lr_t*)HW_EPIT_LR_ADDR(x))
+#define HW_EPIT_LR_RD(x) (HW_EPIT_LR(x).U)
+#define HW_EPIT_LR_WR(x, v) (HW_EPIT_LR(x).U = (v))
+#define HW_EPIT_LR_SET(x, v) (HW_EPIT_LR_WR(x, HW_EPIT_LR_RD(x) | (v)))
+#define HW_EPIT_LR_CLR(x, v) (HW_EPIT_LR_WR(x, HW_EPIT_LR_RD(x) & ~(v)))
+#define HW_EPIT_LR_TOG(x, v) (HW_EPIT_LR_WR(x, HW_EPIT_LR_RD(x) ^ (v)))
+#endif
+//@}
+
+/*
+ * constants & macros for individual EPIT_LR bitfields
+ */
+
+/*! @name Register EPIT_LR, field LOAD[31:0] (RW)
+ *
+ * Load value. Value that is loaded into the counter at the start of each count cycle.
+ */
+//@{
+#define BP_EPIT_LR_LOAD (0) //!< Bit position for EPIT_LR_LOAD.
+#define BM_EPIT_LR_LOAD (0xffffffff) //!< Bit mask for EPIT_LR_LOAD.
+
+//! @brief Get value of EPIT_LR_LOAD from a register value.
+#define BG_EPIT_LR_LOAD(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_LR_LOAD) >> BP_EPIT_LR_LOAD)
+
+//! @brief Format value for bitfield EPIT_LR_LOAD.
+#define BF_EPIT_LR_LOAD(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_LR_LOAD) & BM_EPIT_LR_LOAD)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the LOAD field to a new value.
+#define BW_EPIT_LR_LOAD(x, v) (HW_EPIT_LR_WR(x, (HW_EPIT_LR_RD(x) & ~BM_EPIT_LR_LOAD) | BF_EPIT_LR_LOAD(v)))
+#endif
+//@}
+
+//-------------------------------------------------------------------------------------------
+// HW_EPIT_CMPR - Compare register
+//-------------------------------------------------------------------------------------------
+
+#ifndef __LANGUAGE_ASM__
+/*!
+ * @brief HW_EPIT_CMPR - Compare register (RW)
+ *
+ * Reset value: 0x00000000
+ *
+ * The EPIT compare register (EPIT_CMPR) holds the value that determines when a compare event is
+ * generated.
+ */
+typedef union _hw_epit_cmpr {
+ reg32_t U;
+ struct _hw_epit_cmpr_bitfields {
+ unsigned COMPARE : 32; //!< [31:0] Compare Value.
+ } B;
+} hw_epit_cmpr_t;
+#endif
+
+/*!
+ * @name Constants and macros for entire EPIT_CMPR register
+ */
+//@{
+#define HW_EPIT_CMPR_ADDR(x) (REGS_EPIT_BASE(x) + 0xc)
+
+#ifndef __LANGUAGE_ASM__
+#define HW_EPIT_CMPR(x) (*(volatile hw_epit_cmpr_t*)HW_EPIT_CMPR_ADDR(x))
+#define HW_EPIT_CMPR_RD(x) (HW_EPIT_CMPR(x).U)
+#define HW_EPIT_CMPR_WR(x, v) (HW_EPIT_CMPR(x).U = (v))
+#define HW_EPIT_CMPR_SET(x, v) (HW_EPIT_CMPR_WR(x, HW_EPIT_CMPR_RD(x) | (v)))
+#define HW_EPIT_CMPR_CLR(x, v) (HW_EPIT_CMPR_WR(x, HW_EPIT_CMPR_RD(x) & ~(v)))
+#define HW_EPIT_CMPR_TOG(x, v) (HW_EPIT_CMPR_WR(x, HW_EPIT_CMPR_RD(x) ^ (v)))
+#endif
+//@}
+
+/*
+ * constants & macros for individual EPIT_CMPR bitfields
+ */
+
+/*! @name Register EPIT_CMPR, field COMPARE[31:0] (RW)
+ *
+ * Compare Value. When the counter value equals this bit field value a compare event is generated.
+ */
+//@{
+#define BP_EPIT_CMPR_COMPARE (0) //!< Bit position for EPIT_CMPR_COMPARE.
+#define BM_EPIT_CMPR_COMPARE (0xffffffff) //!< Bit mask for EPIT_CMPR_COMPARE.
+
+//! @brief Get value of EPIT_CMPR_COMPARE from a register value.
+#define BG_EPIT_CMPR_COMPARE(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CMPR_COMPARE) >> BP_EPIT_CMPR_COMPARE)
+
+//! @brief Format value for bitfield EPIT_CMPR_COMPARE.
+#define BF_EPIT_CMPR_COMPARE(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_EPIT_CMPR_COMPARE) & BM_EPIT_CMPR_COMPARE)
+
+#ifndef __LANGUAGE_ASM__
+//! @brief Set the COMPARE field to a new value.
+#define BW_EPIT_CMPR_COMPARE(x, v) (HW_EPIT_CMPR_WR(x, (HW_EPIT_CMPR_RD(x) & ~BM_EPIT_CMPR_COMPARE) | BF_EPIT_CMPR_COMPARE(v)))
+#endif
+//@}
+
+//-------------------------------------------------------------------------------------------
+// HW_EPIT_CNR - Counter register
+//-------------------------------------------------------------------------------------------
+
+#ifndef __LANGUAGE_ASM__
+/*!
+ * @brief HW_EPIT_CNR - Counter register (RO)
+ *
+ * Reset value: 0xffffffff
+ *
+ * The EPIT counter register (EPIT_CNR) contains the current count value and can be read at any time
+ * without disturbing the counter. This is a read-only register and any attempt to write into it
+ * generates a transfer error. But if the IOVW bit in EPIT_CR is set, the value of this register can
+ * be overwritten with a write to EPIT_LR. This change is reflected when this register is
+ * subsequently read.
+ */
+typedef union _hw_epit_cnr {
+ reg32_t U;
+ struct _hw_epit_cnr_bitfields {
+ unsigned COUNT : 32; //!< [31:0] Counter value.
+ } B;
+} hw_epit_cnr_t;
+#endif
+
+/*!
+ * @name Constants and macros for entire EPIT_CNR register
+ */
+//@{
+#define HW_EPIT_CNR_ADDR(x) (REGS_EPIT_BASE(x) + 0x10)
+
+#ifndef __LANGUAGE_ASM__
+#define HW_EPIT_CNR(x) (*(volatile hw_epit_cnr_t*)HW_EPIT_CNR_ADDR(x))
+#define HW_EPIT_CNR_RD(x) (HW_EPIT_CNR(x).U)
+#endif
+//@}
+
+/*
+ * constants & macros for individual EPIT_CNR bitfields
+ */
+
+/*! @name Register EPIT_CNR, field COUNT[31:0] (RO)
+ *
+ * Counter value. This contains the current value of the counter.
+ */
+//@{
+#define BP_EPIT_CNR_COUNT (0) //!< Bit position for EPIT_CNR_COUNT.
+#define BM_EPIT_CNR_COUNT (0xffffffff) //!< Bit mask for EPIT_CNR_COUNT.
+
+//! @brief Get value of EPIT_CNR_COUNT from a register value.
+#define BG_EPIT_CNR_COUNT(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_EPIT_CNR_COUNT) >> BP_EPIT_CNR_COUNT)
+//@}
+
+//-------------------------------------------------------------------------------------------
+// hw_epit_t - module struct
+//-------------------------------------------------------------------------------------------
+/*!
+ * @brief All EPIT module registers.
+ */
+#ifndef __LANGUAGE_ASM__
+#pragma pack(1)
+typedef struct _hw_epit {
+ volatile hw_epit_cr_t CR; //!< Control register
+ volatile hw_epit_sr_t SR; //!< Status register
+ volatile hw_epit_lr_t LR; //!< Load register
+ volatile hw_epit_cmpr_t CMPR; //!< Compare register
+ volatile hw_epit_cnr_t CNR; //!< Counter register
+} hw_epit_t;
+#pragma pack()
+
+//! @brief Macro to access all EPIT registers.
+//! @param x EPIT instance number.
+//! @return Reference (not a pointer) to the registers struct. To get a pointer to the struct,
+//! use the '&' operator, like &HW_EPIT(0)
.
+#define HW_EPIT(x) (*(hw_epit_t*)REGS_EPIT_BASE(x))
+#endif
+
+#endif // __HW_EPIT_REGISTERS_H__
+// v18/121106/1.2.2
+// EOF
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/cortexA9.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/cortexA9.S
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/include/cortex_a9.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/include/cortex_a9.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/include/xil_assert.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/include/xil_assert.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/include/xil_types.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/include/xil_types.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/core.h
index c9667450f..9312dfa79 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/core.h
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/core.h
@@ -33,7 +33,7 @@ Modification:
#define NO_INT 0x80 // disable IRQ.
#define DIS_INT 0xc0 // disable both IRQ and FIQ.
-#define MODE_STACK_SIZE 0x1000
+#define MODE_STACK_SIZE 0x2000
//! @name SPSR fields
//@{
@@ -75,6 +75,13 @@ Modification:
#define NR_CPU 4 // maximum number of CPUs
+static inline uintptr_t arch_curr_tick()
+{
+ uint64_t x;
+ __asm__ volatile("mrs %0, cntpct_el0" : "=r"(x));
+ return x;
+}
+
__attribute__((always_inline)) static inline uint64_t EL0_mode() // Set ARM mode to EL0
{
uint64_t val = 0;
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/include/registers.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/include/registers.h
new file mode 100644
index 000000000..d3c08b923
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/include/registers.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2020 AIIT XUOS Lab
+ * XiUOS is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+#ifndef INC_SYSREGS_H_
+#define INC_SYSREGS_H_
+
+/* SCTLR_EL1, System Control Register (EL1). */
+#define SCTLR_RESERVED \
+ ((3 << 28) | (3 << 22) | (1 << 20) | (1 << 11) | (1 << 8) | (1 << 7))
+#define SCTLR_EE_LITTLE_ENDIAN (0 << 25)
+#define SCTLR_E0E_LITTLE_ENDIAN (0 << 24)
+#define SCTLR_I_CACHE (1 << 12)
+#define SCTLR_D_CACHE (1 << 2)
+#define SCTLR_MMU_DISABLED (0 << 0)
+#define SCTLR_MMU_ENABLED (1 << 0)
+
+#define SCTLR_VALUE_MMU_DISABLED \
+ (SCTLR_RESERVED | SCTLR_EE_LITTLE_ENDIAN | SCTLR_E0E_LITTLE_ENDIAN \
+ | SCTLR_I_CACHE | SCTLR_D_CACHE | SCTLR_MMU_DISABLED)
+
+/* HCR_EL2, Hypervisor Configuration Register (EL2). */
+#define HCR_RW (1 << 31)
+#define HCR_VALUE HCR_RW
+
+/* CPACR_EL1, Architectural Feature Access Control Register. */
+#define CPACR_FP_EN (3 << 20)
+#define CPACR_TRACE_EN (0 << 28)
+#define CPACR_VALUE (CPACR_FP_EN | CPACR_TRACE_EN)
+
+/* SCR_EL3, Secure Configuration Register (EL3). */
+#define SCR_RESERVED (3 << 4)
+#define SCR_RW (1 << 10)
+#define SCR_HCE (1 << 8)
+#define SCR_SMD (1 << 7)
+#define SCR_NS (1 << 0)
+#define SCR_VALUE (SCR_RESERVED | SCR_RW | SCR_HCE | SCR_SMD | SCR_NS)
+
+/* SPSR_EL1/2/3, Saved Program Status Register. */
+#define SPSR_MASK_ALL (7 << 6)
+#define SPSR_EL1h (5 << 0)
+#define SPSR_EL2h (9 << 0)
+#define SPSR_EL3_VALUE (SPSR_MASK_ALL | SPSR_EL2h)
+#define SPSR_EL2_VALUE (SPSR_MASK_ALL | SPSR_EL1h)
+
+/* Exception Class in ESR_EL1. */
+#define EC_SHIFT 26
+#define EC_UNKNOWN 0x00
+#define EC_SVC64 0x15
+#define EC_DABORT 0x24
+#define EC_IABORT 0x20
+
+#define PTE_VALID 1 // level 0,1,2 descriptor: valid
+#define PTE_TABLE 2 // level 0,1,2 descriptor: table
+#define PTE_V 3 // level 3 descriptor: valid
+// PTE_AF(Access Flag)
+//
+// 0 -- this block entry has not yet.
+// 1 -- this block entry has been used.
+#define PTE_AF (1 << 10)
+// PTE_AP(Access Permission) is 2bit field.
+// EL0 EL1
+// 00 -- x RW
+// 01 -- RW RW
+// 10 -- x RO
+// 11 -- RO RO
+#define PTE_AP(ap) (((ap) & 3) << 6)
+#define PTE_U PTE_AP(1)
+#define PTE_RO PTE_AP(2)
+#define PTE_URO PTE_AP(3)
+#define PTE_PXN (1UL << 53) // Privileged eXecute Never
+#define PTE_UXN (1UL << 54) // Unprivileged(user) eXecute Never
+#define PTE_XN (PTE_PXN | PTE_UXN) // eXecute Never
+
+// attribute index
+// index is set by mair_el1
+#define AI_DEVICE_nGnRnE_IDX 0x0
+#define AI_NORMAL_NC_IDX 0x1
+
+// memory type
+#define MT_DEVICE_nGnRnE 0x0
+#define MT_NORMAL_NC 0x44
+
+#define PTE_INDX(i) (((i) & 7) << 2)
+#define PTE_DEVICE PTE_INDX(AI_DEVICE_nGnRnE_IDX)
+#define PTE_NORMAL PTE_INDX(AI_NORMAL_NC_IDX)
+
+// shift a physical address to the right place for a PTE.
+#define PA2PTE(pa) ((uint64_t)(pa) & 0xfffffffff000)
+#define PTE2PA(pte) ((uint64_t)(pte) & 0xfffffffff000)
+
+#define PTE_FLAGS(pte) ((pte) & (0x600000000003ff))
+
+// translation control register
+// #define TCR_T0SZ(n) ((n) & 0x3f)
+// #define TCR_TG0(n) (((n) & 0x3) << 14)
+// #define TCR_T1SZ(n) (((n) & 0x3f) << 16)
+// #define TCR_TG1(n) (((n) & 0x3) << 30)
+// #define TCR_IPS(n) (((n) & 0x7) << 32)
+
+#define ISS_MASK 0xFFFFFF
+
+#endif // INC_SYSREGS_H_
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/Makefile
index 596b31fca..5c955dbf3 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/Makefile
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/cache/L1/Makefile
@@ -1,6 +1,4 @@
-ifneq ($(findstring $(BOARD), 3568 imx6q-sabrelite zynq7000-zc702), )
SRC_DIR := arm
-endif
ifneq ($(findstring $(BOARD), jh7110), )
SRC_DIR := riscv
endif
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/clock/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/clock/Makefile
index 596b31fca..a58d35261 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/clock/Makefile
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/clock/Makefile
@@ -1,6 +1,4 @@
-ifneq ($(findstring $(BOARD), 3568 imx6q-sabrelite zynq7000-zc702), )
-SRC_DIR := arm
-endif
+SRC_DIR:= arm
ifneq ($(findstring $(BOARD), jh7110), )
SRC_DIR := riscv
endif
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/include/xscutimer.h b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/include/xscutimer.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/include/xscutimer_hw.h b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/include/xscutimer_hw.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer.c b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer_g.c b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer_g.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer_selftest.c b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer_selftest.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer_sinit.c b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/zynq7000-zc702/xscutimer_sinit.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c
index d2d0a6f14..bd8a76cea 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c
@@ -129,7 +129,7 @@ static bool xizi_gpt_init()
return false;
}
// register clock handler to intr
- struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&intr_driver_tag);
+ struct XiziTrapDriver* p_intr_driver = GetSysObject(struct XiziTrapDriver, &intr_driver_tag);
p_intr_driver->bind_irq_handler(p_clock_driver->get_clock_int(), xizi_clock_handler);
p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), 0, 0);
return true;
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/intr/Makefile
index 4fcd6940b..fd2efb12b 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/Makefile
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/Makefile
@@ -1,10 +1,7 @@
-ifneq ($(findstring $(BOARD), 3568 imx6q-sabrelite zynq7000-zc702), )
SRC_DIR := arm
-endif
ifneq ($(findstring $(BOARD), jh7110), )
SRC_DIR := riscv
endif
-
SRC_FILES := spinlock.c
include $(KERNEL_ROOT)/compiler.mk
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xil_exception.h b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xil_exception.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic.h b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_g.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_g.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_hw.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_hw.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_hw.h b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_hw.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_intr.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_intr.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_sinit.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xscugic_sinit.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xstatus.h b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/gicv3/xstatus.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c
index f76b56719..51aab3bad 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c
@@ -57,7 +57,7 @@ void panic(char* s)
/* stack for different mode*/
static char mode_stack_pages[NR_CPU][NR_MODE_STACKS][MODE_STACK_SIZE];
extern uint32_t _vector_jumper;
-extern uint32_t _vector_start;
+extern uint32_t* _vector_start;
extern uint32_t _vector_end;
void init_cpu_mode_stacks(int cpu_id)
@@ -75,7 +75,7 @@ static void _sys_irq_init(int cpu_id)
/* load exception vectors */
init_cpu_mode_stacks(cpu_id);
if (cpu_id == 0) {
- volatile uint32_t* vector_base = &_vector_start;
+ volatile uint32_t* vector_base = (uint32_t*)&_vector_start;
// Set Interrupt handler start address
vector_base[1] = (uint32_t)trap_undefined_instruction; // Undefined Instruction
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/xil_assert.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/xil_assert.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/Makefile
index aaba3c920..7653fcf2f 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/Makefile
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/Makefile
@@ -1,6 +1,4 @@
-ifneq ($(findstring $(BOARD), 3568 imx6q-sabrelite zynq7000-zc702), )
SRC_DIR := arm
-endif
ifneq ($(findstring $(BOARD), jh7110), )
SRC_DIR := riscv
endif
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h
index 0a31e0241..1438f964c 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h
@@ -73,4 +73,11 @@ Modification:
#define KERN_MEM_BASE (0x90000000) // First kernel virtual address
#define KERN_OFFSET (KERN_MEM_BASE - PHY_MEM_BASE)
+/* virtual and physical addr translate */
+#define V2P(a) ((uint32_t)((uint32_t)(a)-KERN_OFFSET))
+#define P2V(a) ((void*)((void*)(a) + KERN_OFFSET))
+
+#define V2P_WO(x) ((x)-KERN_OFFSET) // same as V2P, but without casts
+#define P2V_WO(x) ((x) + KERN_OFFSET) // same as V2P, but without casts
+
// clang-format on
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/include/mmu.h b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/include/mmu.h
index 7f5053d19..d5136d838 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/include/mmu.h
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/include/mmu.h
@@ -92,13 +92,6 @@ When the process switches, the flush TLB is no longer required anymore.
#define CONTEXTIDR_R(val) __asm__ volatile("mrc p15, 0, %0, c13, c0, 1" : "=r"(val))
#define CONTEXTIDR_W(val) __asm__ volatile("mcr p15, 0, %0, c13, c0, 1" ::"r"(val))
-/* virtual and physical addr translate */
-#define V2P(a) ((uint32_t)((uint32_t)(a)-KERN_OFFSET))
-#define P2V(a) ((void*)((void*)(a) + KERN_OFFSET))
-
-#define V2P_WO(x) ((x)-KERN_OFFSET) // same as V2P, but without casts
-#define P2V_WO(x) ((x) + KERN_OFFSET) // same as V2P, but without casts
-
#ifndef __ASSEMBLER__
#include
__attribute__((always_inline)) static inline uint32_t v2p(void* a) { return ((uint32_t)(a)) - KERN_MEM_BASE; }
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv8-a/cortex-a55/3568/memlayout.h b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv8-a/cortex-a55/3568/memlayout.h
index ef7e8ef24..5979533bb 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv8-a/cortex-a55/3568/memlayout.h
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv8-a/cortex-a55/3568/memlayout.h
@@ -36,8 +36,8 @@ Modification:
/* A55 physical memory layout */
#define PHY_MEM_BASE (0x0000000010000000ULL)
#define PHY_USER_FREEMEM_BASE (0x0000000040000000ULL)
-#define PHY_USER_FREEMEM_TOP (0x00000000e0000000ULL)
-#define PHY_MEM_STOP (0x00000000e0000000ULL)
+#define PHY_USER_FREEMEM_TOP (0x00000000E0000000ULL)
+#define PHY_MEM_STOP (0x00000000E0000000ULL)
/* PTE-PAGE_SIZE */
#define LEVEL4_PTE_SHIFT 12
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/uart/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/uart/Makefile
index f18170cb0..2559ece3e 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/uart/Makefile
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/uart/Makefile
@@ -1,10 +1,7 @@
-ifneq ($(findstring $(BOARD), 3568 imx6q-sabrelite zynq7000-zc702), )
SRC_DIR := arm
-endif
ifneq ($(findstring $(BOARD), jh7110), )
SRC_DIR := riscv
endif
-
SRC_FILES := uart_common_ope.c
include $(KERNEL_ROOT)/compiler.mk
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_imx6q-sabrelite/imx_uart.c b/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_imx6q-sabrelite/imx_uart.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xil_io.h b/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xil_io.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xpseudo_asm.h b/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xpseudo_asm.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xpseudo_asm_gcc.h b/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xpseudo_asm_gcc.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xreg_cortexa9.h b/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/include/xreg_cortexa9.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/xil_io.c b/Ubiquitous/XiZi_AIoT/hardkernel/uart/arm/armv7-a/cortex-a9/uart_io_for_zynq7000-zc702/xil_io.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/uart/printf.h b/Ubiquitous/XiZi_AIoT/hardkernel/uart/printf.h
index ed0bd0d3b..fdff3da0d 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/uart/printf.h
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/uart/printf.h
@@ -101,5 +101,4 @@ int fctprintf(void (*out)(char character, void* arg), void* arg, const char* for
}
#endif
-#endif // _PRINTF_H_
-
+#endif // _PRINTF_H_
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/uart/uart_common_ope.c b/Ubiquitous/XiZi_AIoT/hardkernel/uart/uart_common_ope.c
index 4aa8f0939..a500d147d 100644
--- a/Ubiquitous/XiZi_AIoT/hardkernel/uart/uart_common_ope.c
+++ b/Ubiquitous/XiZi_AIoT/hardkernel/uart/uart_common_ope.c
@@ -897,7 +897,6 @@ int fctprintf(void (*out)(char character, void* arg), void* arg, const char* for
return ret;
}
-///////////////////////////////////////////////////////////////////////////////
__attribute__((weak)) void _debug_uart_putc(int ch) {}
static inline void _out_char_early(char character, void* buffer, size_t idx, size_t maxlen)
diff --git a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c
index f74596559..d1b9bd0c7 100644
--- a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c
+++ b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c
@@ -41,15 +41,16 @@ static void tracer_init_node(TracerNode* node, char* name, tracemeta_ac_type typ
node->parent = NULL;
if (name != NULL) {
char* p_name = (char*)slab_alloc(&sys_tracer.node_name_allocator);
- strcpy(p_name, name);
- p_name[TRACER_NODE_NAME_LEN - 1] = '\0';
- node->name = p_name;
- }
- if (node->type == TRACER_OWNER) {
- doubleListNodeInit(&node->children_guard);
- } else {
- node->p_resource = p_resource;
+ if (!p_name) {
+ p_name = "BAD_NAME(NOMEM)";
+ } else {
+ strcpy(p_name, name);
+ p_name[TRACER_NODE_NAME_LEN - 1] = '\0';
+ node->name = p_name;
+ }
}
+ doubleListNodeInit(&node->children_guard);
+ node->p_resource = p_resource;
doubleListNodeInit(&node->list_node);
}
@@ -61,8 +62,8 @@ void sys_tracer_init()
sys_tracer.sys_tracer_tag.meta = &sys_tracer.root_node;
// init memory allocator
- slab_init(&sys_tracer.node_allocator, sizeof(TracerNode));
- slab_init(&sys_tracer.node_name_allocator, sizeof(char[TRACER_NODE_NAME_LEN]));
+ slab_init(&sys_tracer.node_allocator, sizeof(TracerNode), "TracerNodeAllocator");
+ slab_init(&sys_tracer.node_name_allocator, sizeof(char[TRACER_NODE_NAME_LEN]), "TracerNodeNameAllocator");
}
static char* parse_path(char* path, char* const name)
@@ -84,7 +85,7 @@ static char* parse_path(char* path, char* const name)
// handle current name
int len = path - cur_start;
if (len >= TRACER_NODE_NAME_LEN) {
- strncpy(name, cur_start, TRACER_NODE_NAME_LEN);
+ strncpy(name, cur_start, TRACER_NODE_NAME_LEN - 1);
name[TRACER_NODE_NAME_LEN - 1] = '\0';
} else {
strncpy(name, cur_start, len);
@@ -149,11 +150,12 @@ bool CreateResourceTag(TraceTag* new_tag, TraceTag* owner, char* name, tracemeta
{
assert(owner != NULL);
if (owner->meta == NULL) {
- ERROR("Tracer: Empty owner\n");
+ ERROR("Tracer: Empty owner, node name: %s\n", name);
return false;
}
- assert(owner->meta->type == TRACER_OWNER);
- if (tracer_find_node_onestep(owner->meta, name) != NULL) {
+ // assert(owner->meta->type == TRACER_OWNER);
+ if (type == TRACER_SERVER_IDENTITY_AC_RESOURCE && //
+ tracer_find_node_onestep(owner->meta, name) != NULL) {
return false;
}
@@ -179,7 +181,7 @@ bool DeleteResource(TraceTag* target, TraceTag* owner)
assert(target != NULL && owner != NULL);
assert(owner->meta != NULL && owner->meta->type == TRACER_OWNER);
if (target->meta == NULL) {
- ERROR("Tracer: Delete a empty resource\n");
+ ERROR("Tracer: Delete a empty resource, owner: %s\n", owner->meta->name);
return false;
}
@@ -204,27 +206,37 @@ bool DeleteResource(TraceTag* target, TraceTag* owner)
return true;
}
-void debug_list_tracetree_inner(TracerNode* cur_node)
+#define debug_print_blanks(n) \
+ for (int __i = 0; __i < n; __i++) { \
+ DEBUG_PRINTF(" "); \
+ }
+
+void debug_list_tracetree_inner(TracerNode* cur_node, int nr_blanks)
{
- DEBUG("[%s] ", cur_node->name);
+ debug_print_blanks(nr_blanks);
+ if (cur_node->name == NULL) {
+ DEBUG_PRINTF("[ANON %d] ", cur_node->type);
+ } else {
+ DEBUG_PRINTF("[%s %d] ", cur_node->name, cur_node->type);
+ }
TracerNode* tmp = NULL;
DOUBLE_LIST_FOR_EACH_ENTRY(tmp, &cur_node->children_guard, list_node)
{
if (tmp->name != NULL) {
- DEBUG("%s ", tmp->name);
+ DEBUG_PRINTF("%s ", tmp->name);
} else {
- DEBUG("ANON ");
+ DEBUG_PRINTF("ANON ");
}
}
- DEBUG("\n");
+ DEBUG_PRINTF("\n");
DOUBLE_LIST_FOR_EACH_ENTRY(tmp, &cur_node->children_guard, list_node)
{
- debug_list_tracetree_inner(tmp);
+ debug_list_tracetree_inner(tmp, nr_blanks + 1);
}
}
void debug_list_tracetree()
{
TracerNode* ref_root = RequireRootTag()->meta;
- debug_list_tracetree_inner(ref_root);
+ debug_list_tracetree_inner(ref_root, 0);
}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.h b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.h
index 06f819c6a..a2a9f3e0d 100644
--- a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.h
+++ b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.h
@@ -30,35 +30,12 @@ Modification:
#include
#include
-#include "list.h"
+#include "actracer_tag.h"
#include "object_allocator.h"
#define TRACER_NODE_NAME_LEN 32
-typedef enum {
- TRACER_INVALID = 0,
- TRACER_OWNER,
- TRACER_HARDKERNEL_AC_RESOURCE,
- TRACER_TASK_DESCRIPTOR_AC_RESOURCE,
- TRACER_SERVER_IDENTITY_AC_RESOURCE,
- TRACER_MEM_FROM_BUDDY_AC_RESOURCE,
-} tracemeta_ac_type;
-
-typedef struct TracerNode {
- tracemeta_ac_type type;
- char* name;
- union {
- struct double_list_node children_guard;
- void* p_resource;
- };
- struct TracerNode* parent;
- struct double_list_node list_node;
-} TracerNode;
-
-/// @brief tag for other module to reference trace meta
-typedef struct TraceTag {
- TracerNode* meta;
-} TraceTag;
+#define GetSysObject(type, target_tag) (type*)AchieveResource(target_tag)
struct SysTracer {
TracerNode root_node;
@@ -72,4 +49,6 @@ TraceTag* const RequireRootTag();
bool AchieveResourceTag(struct TraceTag* target, struct TraceTag* owner, char* name);
void* AchieveResource(struct TraceTag* tag);
bool CreateResourceTag(struct TraceTag* new_tag, struct TraceTag* owner, char* name, tracemeta_ac_type type, void* p_resource);
-bool DeleteResource(struct TraceTag* target, struct TraceTag* owner);
\ No newline at end of file
+bool DeleteResource(struct TraceTag* target, struct TraceTag* owner);
+
+void debug_list_tracetree();
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_tag.h b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_tag.h
new file mode 100644
index 000000000..b2152cc59
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_tag.h
@@ -0,0 +1,26 @@
+#pragma once
+#include "list.h"
+
+typedef enum {
+ TRACER_INVALID = 0,
+ TRACER_OWNER,
+ TRACER_HARDKERNEL_AC_RESOURCE,
+ TRACER_TASK_DESCRIPTOR_AC_RESOURCE,
+ TRACER_SERVER_IDENTITY_AC_RESOURCE,
+ TRACER_MEM_SIGNATURE,
+ TRACER_SYSOBJECT,
+} tracemeta_ac_type;
+
+typedef struct TracerNode {
+ tracemeta_ac_type type;
+ char* name;
+ void* p_resource;
+ struct TracerNode* parent;
+ struct double_list_node list_node;
+ struct double_list_node children_guard;
+} TracerNode;
+
+/// @brief tag for other module to reference trace meta
+typedef struct TraceTag {
+ TracerNode* meta;
+} TraceTag;
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/path_kernel.mk b/Ubiquitous/XiZi_AIoT/path_kernel.mk
old mode 100755
new mode 100644
index 7282780e2..d7b847c5a
--- a/Ubiquitous/XiZi_AIoT/path_kernel.mk
+++ b/Ubiquitous/XiZi_AIoT/path_kernel.mk
@@ -63,7 +63,6 @@ KERNELPATHS += \
-I$(KERNEL_ROOT)/hardkernel/clock/riscv/rv64gc/$(BOARD)/include \
-I$(KERNEL_ROOT)/hardkernel/intr/riscv/rv64gc/ \
-I$(KERNEL_ROOT)/hardkernel/intr/riscv/rv64gc/$(BOARD) \
- -I$(KERNEL_ROOT)/hardkernel/intr/riscv/rv64gc/gicv3 \
-I$(KERNEL_ROOT)/hardkernel/mmu/riscv/rv64gc/include \
-I$(KERNEL_ROOT)/hardkernel/mmu/riscv/rv64gc/$(BOARD) \
-I$(KERNEL_ROOT)/hardkernel/uart/riscv/rv64gc/uart_io_for_$(BOARD)/include \
diff --git a/Ubiquitous/XiZi_AIoT/services/Makefile b/Ubiquitous/XiZi_AIoT/services/Makefile
index 873b26eef..3c11c6976 100644
--- a/Ubiquitous/XiZi_AIoT/services/Makefile
+++ b/Ubiquitous/XiZi_AIoT/services/Makefile
@@ -1,7 +1,7 @@
ifeq ($(BOARD), jh7110)
SRC_DIR := fs shell lib boards tools app
else
-SRC_DIR := fs shell lib boards drivers semaphore drivers tools net app
+SRC_DIR := fs shell lib boards drivers semaphore tools app
endif
include $(KERNEL_ROOT)/compiler.mk
diff --git a/Ubiquitous/XiZi_AIoT/services/app/.gitignore b/Ubiquitous/XiZi_AIoT/services/app/.gitignore
new file mode 100644
index 000000000..46078f320
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/services/app/.gitignore
@@ -0,0 +1,3 @@
+bin
+fs.img
+user.map
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/services/app/Makefile b/Ubiquitous/XiZi_AIoT/services/app/Makefile
index 2575bfa7e..368c7edc5 100644
--- a/Ubiquitous/XiZi_AIoT/services/app/Makefile
+++ b/Ubiquitous/XiZi_AIoT/services/app/Makefile
@@ -50,12 +50,23 @@ INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \
-I$(KERNEL_ROOT)/services/app
ifeq ($(BOARD), imx6q-sabrelite)
-all: test_fault simple_client simple_server shell fs_server semaphore_server test_semaphore test_ipc_null test_thread test_irq_hdlr test_irq_block test_irq_send eth_driver epit_server test_net lwip readme.txt | bin
+all: pingpong_client pingpong_server \
+ test_fault simple_client simple_server \
+ shell fs_server semaphore_server \
+ test_sleep test_semaphore test_ipc_null test_thread test_irq_hdlr test_irq_block test_irq_send \
+ eth_driver epit_server readme.txt | bin
else
ifeq ($(BOARD), jh7110)
-all: shell fs_server | bin
+all: shell fs_server \
+ | bin
else
-all: test_fault simple_client simple_server shell fs_server semaphore_server test_ipc_null test_thread test_semaphore test_net lwip readme.txt eth_hal | bin
+all: pingpong_client pingpong_server \
+ test_fault simple_client simple_server \
+ shell fs_server semaphore_server \
+ test_irq_hdlr \
+ test_sleep test_ipc_null test_thread test_semaphore readme.txt \
+ test_context_user \
+ | bin
endif
endif
../tools/mkfs/mkfs ./fs.img $^
@@ -80,6 +91,22 @@ epit_server: timer.o epit.o ccm_pll.o usyscall.o arch_usyscall.o libserial.o pri
@${objdump} -S $@ > $@.asm
endif
+pingpong_client: pingpong_service.o pingpong_client.o libserial.o printf.o libipc.o session.o libfs.o usyscall.o arch_usyscall.o libmem.o
+ @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
+ @${objdump} -S $@ > $@.asm
+
+pingpong_server: pingpong_service.o pingpong_server.o libserial.o printf.o libipc.o session.o libfs.o usyscall.o arch_usyscall.o libmem.o
+ @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
+ @${objdump} -S $@ > $@.asm
+
+test_sleep: test_sleep.o libserial.o printf.o usyscall.o arch_usyscall.o
+ @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
+ @${objdump} -S $@ > $@.asm
+
+test_context_user: test_context_user.o libserial.o printf.o usyscall.o arch_usyscall.o
+ @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
+ @${objdump} -S $@ > $@.asm
+
test_semaphore: test_semaphore.o libserial.o printf.o usyscall.o arch_usyscall.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
@@ -136,8 +163,4 @@ test_net: test_net.o lwip_service.o libipc.o session.o libserial.o printf.o usys
@${cc} ${cflags} ${c_useropts} ${INC_DIR} -o $@ -c $<
%.o: %.S
- @${cc} ${cflags} ${c_useropts} -o $@ -c $<
-
-eth_hal: test_gmac.o hal_gmac.o hal_gmac_3568.o hal_base.o hal_bsp.o hal_pinctrl_v2.o hal_cru.o hal_gpio.o hal_timer.o hal_cru_rk3568.o system_rk3568.o hal_debug.o libserial.o printf.o libmem.o usyscall.o arch_usyscall.o session.o libipc.o
- @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
- @${objdump} -S $@ > $@.asm
\ No newline at end of file
+ @${cc} ${cflags} ${c_useropts} -o $@ -c $<
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/services/app/pingpong_client.c b/Ubiquitous/XiZi_AIoT/services/app/pingpong_client.c
new file mode 100644
index 000000000..400bf0f8a
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/services/app/pingpong_client.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2020 AIIT XUOS Lab
+ * XiUOS is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+#include
+#include
+#include
+#include
+
+#include "libfs.h"
+#include "libserial.h"
+#include "pingpong_service.h"
+#include "usyscall.h"
+
+int string_to_integer(const char* str)
+{
+ assert(str);
+ while (*str == ' ') {
+ str++;
+ }
+ int is_positive = 1; // 默认是正
+ if (*str - '+' == 0) {
+ is_positive = 1;
+ str++;
+ }
+ if (*str - '-' == 0) {
+ is_positive = 0;
+ str++;
+ }
+ long long result = 0; // int可能存不下 改为long long较为合适虽然返回值会丢失精度但感觉不要紧
+ while ('0' <= *str && *str <= '9') {
+ result *= 10;
+ result += *str - '0'; // 如'1' ascii的值为 49 '0'的ascii的值为48 相减得到1
+
+ if (result > INT32_MAX || result < INT32_MIN) // 可能出现的溢出问题
+ {
+ return result > INT32_MAX ? INT32_MAX : INT32_MIN;
+ }
+
+ str++;
+ }
+ return is_positive ? (result) : -result;
+}
+
+void itoa(int num, char* str, int radix)
+{
+ int i = 0;
+ int sum;
+ unsigned int num1 = num; // 如果是负数求补码,必须将他的绝对值放在无符号位中在进行求反码
+ char str1[33] = { 0 };
+ if (num < 0) { // 求出负数的补码
+ num = -num;
+ num1 = ~num;
+ num1 += 1;
+ }
+ if (num == 0) {
+ str1[i] = '0';
+
+ i++;
+ }
+ while (num1 != 0) { // 进行进制运算
+ sum = num1 % radix;
+ str1[i] = (sum > 9) ? (sum - 10) + 'a' : sum + '0';
+ num1 = num1 / radix;
+ i++;
+ }
+ i--;
+ int j = 0;
+ for (i; i >= 0; i--) { // 逆序输出
+ str[i] = str1[j];
+ j++;
+ }
+}
+
+uintptr_t pingpong_sample(struct Session* session, int times)
+{
+ char* msg = "hello";
+ uintptr_t tick1 = sys_test();
+ for (int i = 0; i < times; i++) {
+ uintptr_t tmp = sys_test();
+ }
+ uintptr_t tick2 = sys_test();
+ uintptr_t time = (tick2 - tick1) / 24;
+ // printf("Sync Tick Cost: %lu\n", time);
+ return time;
+}
+
+uintptr_t pingpong_test_sync(struct Session* session, int times)
+{
+ char* msg = "hello";
+ uintptr_t tick1 = sys_test();
+ for (int i = 0; i < times; i++) {
+ pingpong(session, msg);
+ }
+ uintptr_t tick2 = sys_test();
+ uintptr_t time = (tick2 - tick1) / 24;
+ // printf("Sync Tick Cost: %lu\n", time);
+ return time;
+}
+
+uintptr_t pingpong_test_async(struct Session* session, int times)
+{
+ char* msg = "hello";
+ uintptr_t tick1 = sys_test();
+ for (int i = 0; i < times; i++) {
+ pingpong_nowait(session, msg);
+ }
+
+ for (int i = 0; i < times; i++) {
+ ipc_session_wait(session);
+ ipc_session_forward(session);
+ }
+ uintptr_t tick2 = sys_test();
+ uintptr_t time = (tick2 - tick1) / 24;
+ // printf("ASync Tick Cost: %lu\n", (tick2 - tick1) / 24);
+ return time;
+}
+
+int main(int argc, char** argv)
+{
+ int times = 0;
+ if (argc >= 2) {
+ times = string_to_integer(argv[1]);
+ }
+
+ struct Session session;
+ if (connect_session(&session, "PingPongServer", 81920) < 0) {
+ printf("connect session failed\n");
+ exit(1);
+ }
+
+ printf("============ PingPong Test start ==============\n");
+ uintptr_t loop = 50;
+ uintptr_t t1 = 0, t2 = 0, t0 = 0;
+ for (uintptr_t i = 0; i < loop; i++) {
+ t0 += pingpong_sample(&session, times);
+ t1 += pingpong_test_sync(&session, times);
+ t2 += pingpong_test_async(&session, times);
+ }
+
+ printf("Compare Tick Cost: %lu\n", t0 / loop);
+ printf("Sync Tick Cost: %lu\n", t1 / loop);
+ printf("ASync Tick Cost: %lu\n", t2 / loop);
+ printf("============= PingPong Test End ===============\n");
+
+ exit(0);
+}
diff --git a/Ubiquitous/XiZi_AIoT/services/app/pingpong_server.c b/Ubiquitous/XiZi_AIoT/services/app/pingpong_server.c
new file mode 100644
index 000000000..06f16d7af
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/services/app/pingpong_server.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2020 AIIT XUOS Lab
+ * XiUOS is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+#include
+
+#include "libserial.h"
+#include "pingpong_service.h"
+#include "usyscall.h"
+
+/// @warning all the parameters should in the form of pointers
+/// for the true storing memory of parameters is session(shared memory between tasks)
+int IPC_DO_SERVE_FUNC(Ipc_pingpong)(char* str)
+{
+ return 0;
+}
+
+IPC_SERVER_INTERFACE(Ipc_pingpong, 1);
+IPC_SERVER_REGISTER_INTERFACES(IpcPingPongServer, 1, Ipc_pingpong);
+
+int main(int argc, char* argv[])
+{
+ if (register_server("PingPongServer") < 0) {
+ printf("register server name: %s failed.\n", "PingPong");
+ exit(1);
+ }
+ ipc_server_loop(&IpcPingPongServer);
+
+ // never reached
+ exit(0);
+ return 0;
+}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/services/app/pingpong_service.c b/Ubiquitous/XiZi_AIoT/services/app/pingpong_service.c
new file mode 100644
index 000000000..9bc9e49d1
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/services/app/pingpong_service.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020 AIIT XUOS Lab
+ * XiUOS is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+#include "pingpong_service.h"
+
+IPC_INTERFACE(Ipc_pingpong, 1, str, strlen(str));
+int pingpong(struct Session* session, char* str)
+{
+ return IPC_CALL(Ipc_pingpong)(session, str);
+}
+
+void pingpong_nowait(struct Session* session, char* str)
+{
+ struct IpcMsg* msg = IPC_CREATE_MSG_FUNC(Ipc_pingpong)(session, str);
+ ipc_msg_set_nth_arg(msg, 0, str, strlen(str));
+ ipc_msg_set_opcode(msg, Ipc_pingpong);
+ ipc_msg_send_nowait(msg);
+}
diff --git a/Ubiquitous/XiZi_AIoT/services/app/pingpong_service.h b/Ubiquitous/XiZi_AIoT/services/app/pingpong_service.h
new file mode 100644
index 000000000..15e824bd7
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/services/app/pingpong_service.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2020 AIIT XUOS Lab
+ * XiUOS is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+#include
+#include
+
+#include "libipc.h"
+
+IPC_SERVICES(IpcPingPongServer, Ipc_pingpong);
+
+int pingpong(struct Session* session, char* str);
+void pingpong_nowait(struct Session* session, char* str);
diff --git a/Ubiquitous/XiZi_AIoT/services/app/simple_client.c b/Ubiquitous/XiZi_AIoT/services/app/simple_client.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/app/simple_server.c b/Ubiquitous/XiZi_AIoT/services/app/simple_server.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/app/test_context_user.c b/Ubiquitous/XiZi_AIoT/services/app/test_context_user.c
new file mode 100644
index 000000000..9b5eca355
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/services/app/test_context_user.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2020 AIIT XUOS Lab
+ * XiUOS is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+#include "libserial.h"
+#include "usyscall.h"
+
+static inline uintptr_t arch_curr_tick()
+{
+ uint64_t x;
+ __asm__ volatile("mrs %0, cntpct_el0" : "=r"(x));
+ return x;
+}
+
+int main(int argc, char* argv[])
+{
+ uintptr_t loop = 1000;
+ uintptr_t tick_total = 0;
+ for (uintptr_t i = 0; i < loop; i++) {
+ uintptr_t tick_1 = sys_test();
+ uintptr_t tick_2 = sys_test();
+ // printf("TICK before: %lu\n", tick_1);
+ // printf("TICK after: %lu\n", tick_2);
+ // printf("TICK diff: %lu\n", tick_2 - tick_1);
+ tick_total += tick_2 - tick_1;
+ }
+
+ printf("TICK DIFF: %lu\n", tick_total / loop);
+
+ printf("TEST TICK: %lu\n", arch_curr_tick());
+
+ exit(0);
+ return 0;
+}
diff --git a/Ubiquitous/XiZi_AIoT/services/app/test_sleep.c b/Ubiquitous/XiZi_AIoT/services/app/test_sleep.c
new file mode 100644
index 000000000..16c02dd01
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/services/app/test_sleep.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020 AIIT XUOS Lab
+ * XiUOS is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+#include "libserial.h"
+#include "usyscall.h"
+
+int main(int argc, char* argv[])
+{
+ while (true) {
+ printf("sleep for 2 seconds\n");
+ sleep(2000);
+ }
+
+ exit(0);
+}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/services/app/test_thread.c b/Ubiquitous/XiZi_AIoT/services/app/test_thread.c
index b5e212db3..8e7050ef3 100644
--- a/Ubiquitous/XiZi_AIoT/services/app/test_thread.c
+++ b/Ubiquitous/XiZi_AIoT/services/app/test_thread.c
@@ -25,15 +25,9 @@ int sub_thread_entry(int argc, char** argv)
global_value++;
}
- /// @warning session is single threaded, so that each thread cannot share a common session.
// sub thread connect to semaphore server
- struct Session sem_session;
- while (connect_session(&sem_session, sem_server_name, 4096) < 0) {
- yield(SYS_TASK_YIELD_NO_REASON);
- }
-
printf("Thread signal sem.\n");
- sem_signal(&sem_session, &sem);
+ semaphore_signal(sem);
exit(0);
return 0;
@@ -45,39 +39,8 @@ int main(int argc, char** argv)
global_value = 0;
printf("Test Create Semaphore.\n");
- struct Session sem_session;
- bool spawn_sem_server = false;
- while (connect_session(&sem_session, sem_server_name, 4096) < 0) {
- if (!spawn_sem_server) {
- struct Session fs_session;
- printf("Connect FS.\n");
- if (connect_session(&fs_session, "MemFS", 8192) < 0) {
- printf("Connect FS failed.\n");
- exit(1);
- }
-
- printf("Loading semaphore server.\n");
- int fd = -1;
- if ((fd = open(&fs_session, sem_file_name)) < 0) {
- printf("Open %s failed.\n", sem_file_name);
- free_session(&fs_session);
- exit(1);
- }
-
- printf("Spawn semaphore server.\n");
- char* sem_server_params[] = { sem_server_name, sem_server_name, NULL };
- if (spawn(&fs_session, fd, read, fsize, sem_server_name, sem_server_params) < 0) {
- printf("Spawn %s failed.\n", sem_file_name);
- free_session(&fs_session);
- exit(1);
- }
-
- spawn_sem_server = true;
- free_session(&fs_session);
- }
- }
printf("Create new sem.\n");
- sem_create(&sem_session, &sem, 0);
+ sem = semaphore_new(0);
printf("Create new thread.\n");
char* task_param[2] = { "add_gval", NULL };
@@ -91,12 +54,11 @@ int main(int argc, char** argv)
printf("Main thread waiting for sem for %d times.\n", nr_thread);
for (int i = 0; i < nr_thread; i++) {
- int sem_wait_ret = sem_wait(&sem_session, &sem, 0);
+ int sem_wait_ret = semaphore_wait(sem);
}
printf("Main thread sem %d wait return, global val: %d.\n", sem, global_value);
- sem_delete(&sem_session, &sem);
- free_session(&sem_session);
+ semaphore_free(sem);
exit(0);
return 0;
}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/services/boards/3568/arch_usyscall.c b/Ubiquitous/XiZi_AIoT/services/boards/3568/arch_usyscall.c
index cd1bf7b40..f0d0b50e3 100644
--- a/Ubiquitous/XiZi_AIoT/services/boards/3568/arch_usyscall.c
+++ b/Ubiquitous/XiZi_AIoT/services/boards/3568/arch_usyscall.c
@@ -15,6 +15,27 @@ int syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
{
int ret = -1;
+ __asm__ volatile(
+ "mov x0, %1;\
+ mov x1, %2;\
+ mov x2, %3;\
+ mov x3, %4;\
+ mov x4, %5;\
+ svc #0;\
+ dsb ish;\
+ isb;\
+ mov %0, x0"
+ : "=r"(ret)
+ : "r"(sys_num), "r"(a1), "r"(a2), "r"(a3), "r"(a4)
+ : "memory", "r0", "r1", "r2", "r3", "r4");
+
+ return ret;
+}
+
+uintptr_t syscall_ori(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
+{
+ uintptr_t ret = -1;
+
__asm__ volatile(
"mov x0, %1;\
mov x1, %2;\
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/Makefile b/Ubiquitous/XiZi_AIoT/services/drivers/3568/Makefile
index 2c285fffa..6988b8d76 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/Makefile
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/Makefile
@@ -1,4 +1,4 @@
-SRC_DIR := hal
+SRC_DIR :=
include $(KERNEL_ROOT)/compiler.mk
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_base.c b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_base.c
index f83f62cfe..2719e598d 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_base.c
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_base.c
@@ -312,13 +312,12 @@ __attribute__((weak)) HAL_Status HAL_DelayMs(uint32_t ms)
*/
HAL_Status HAL_DelayUs(uint32_t us)
{
-// #if defined(SYS_TIMER) && defined(HAL_TIMER_MODULE_ENABLED)
-
-// return TimerDelayUs(us);
-// #else
+#if defined(SYS_TIMER) && defined(HAL_TIMER_MODULE_ENABLED)
+ return TimerDelayUs(us);
+#else
return HAL_CPUDelayUs(us);
-// #endif
+#endif
}
/**
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_bsp.c b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_bsp.c
index c985ca48f..1fcf721b8 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_bsp.c
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_bsp.c
@@ -321,21 +321,43 @@ const struct HAL_CANFD_DEV g_can2Dev =
#endif
#ifdef HAL_GMAC_MODULE_ENABLED
+// const struct HAL_GMAC_DEV g_gmac0Dev =
+// {
+// .pReg = GMAC0,
+// .clkID = CLK_MAC0_2TOP,
+// .clkGateID = CLK_MAC0_2TOP_GATE,
+// .pclkID = PCLK_PHP,
+// .pclkGateID = PCLK_GMAC0_GATE,
+// .irqNum = GMAC0_IRQn,
+// };
const struct HAL_GMAC_DEV g_gmac0Dev =
{
.pReg = GMAC0,
- .clkID = CLK_MAC0_2TOP,
- .clkGateID = CLK_MAC0_2TOP_GATE,
+ .clkID125M = CLK_MAC0_2TOP,
+ .clkID50M = CLK_MAC0_2TOP,
+ .clkGateID125M = CLK_MAC0_2TOP_GATE,
+ .clkGateID50M = CLK_MAC0_2TOP_GATE,
.pclkID = PCLK_PHP,
.pclkGateID = PCLK_GMAC0_GATE,
.irqNum = GMAC0_IRQn,
};
+// const struct HAL_GMAC_DEV g_gmac1Dev =
+// {
+// .pReg = GMAC1,
+// .clkID = CLK_MAC1_2TOP,
+// .clkGateID = CLK_MAC1_2TOP_GATE,
+// .pclkID = PCLK_USB,
+// .pclkGateID = PCLK_GMAC1_GATE,
+// .irqNum = GMAC1_IRQn,
+// };
const struct HAL_GMAC_DEV g_gmac1Dev =
{
.pReg = GMAC1,
- .clkID = CLK_MAC1_2TOP,
- .clkGateID = CLK_MAC1_2TOP_GATE,
+ .clkID125M = CLK_MAC1_2TOP,
+ .clkID50M = CLK_MAC1_2TOP,
+ .clkGateID125M = CLK_MAC1_2TOP_GATE,
+ .clkGateID50M = CLK_MAC1_2TOP_GATE,
.pclkID = PCLK_USB,
.pclkGateID = PCLK_GMAC1_GATE,
.irqNum = GMAC1_IRQn,
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_cru.c b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_cru.c
index c685a6149..56fa83e86 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_cru.c
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_cru.c
@@ -115,8 +115,8 @@
#define CRU_PLL_ROUND_UP_TO_KHZ(x) (HAL_DIV_ROUND_UP((x), KHZ) * KHZ)
-#define CRU_READ(r) (*(volatile uint32_t *)(r))
-#define CRU_WRITE(r, b, w, v) (*(volatile uint32_t *)(r) = ((w) << (16) | (v) << (b)))
+#define CRU_READ(r) (*(volatile uint32_t *)((uintptr_t)(r)))
+#define CRU_WRITE(r, b, w, v) (*(volatile uint32_t *)((uintptr_t)(r)) = ((w) << (16) | (v) << (b)))
/********************* Private Structure Definition **************************/
static struct PLL_CONFIG g_rockchipAutoTable;
@@ -147,6 +147,22 @@ static int isBetterFreq(uint32_t now, uint32_t new, uint32_t best)
return (new <= now && new > best);
}
+int HAL_CRU_FreqGetMuxArray(uint32_t freq, uint32_t *table, int num)
+{
+ uint32_t best = 0, mux = 0;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ if (isBetterFreq(freq, table[i], best)) {
+ best = table[i];
+ mux = i;
+ break;
+ }
+ }
+
+ return mux;
+}
+
int HAL_CRU_FreqGetMux4(uint32_t freq, uint32_t freq0, uint32_t freq1,
uint32_t freq2, uint32_t freq3)
{
@@ -191,6 +207,17 @@ int HAL_CRU_FreqGetMux2(uint32_t freq, uint32_t freq0, uint32_t freq1)
return HAL_CRU_FreqGetMux4(freq, freq0, freq1, freq1, freq1);
}
+uint32_t HAL_CRU_MuxGetFreqArray(uint32_t muxName, uint32_t *table, int num)
+{
+ uint32_t mux = HAL_CRU_ClkGetMux(muxName);
+
+ if (mux <= (uint32_t)num) {
+ return table[mux];
+ } else {
+ return HAL_INVAL;
+ }
+}
+
uint32_t HAL_CRU_MuxGetFreq4(uint32_t muxName, uint32_t freq0, uint32_t freq1,
uint32_t freq2, uint32_t freq3)
{
@@ -223,6 +250,30 @@ uint32_t HAL_CRU_MuxGetFreq2(uint32_t muxName, uint32_t freq0, uint32_t freq1)
return HAL_CRU_MuxGetFreq4(muxName, freq0, freq1, freq1, freq1);
}
+int HAL_CRU_RoundFreqGetMuxArray(uint32_t freq, uint32_t *table, int num, uint32_t *pFreqOut, bool is_div)
+{
+ uint32_t mux = 0;
+ int i = 0;
+
+ for (i = 0; i < num; i++) {
+ if (is_div) {
+ if (table[i] && (table[i] % freq == 0)) {
+ mux = i;
+ break;
+ }
+ } else {
+ if (table[i] && (table[i] == freq)) {
+ mux = i;
+ break;
+ }
+ }
+ }
+
+ *pFreqOut = table[mux];
+
+ return mux;
+}
+
int HAL_CRU_RoundFreqGetMux4(uint32_t freq, uint32_t pFreq0,
uint32_t pFreq1, uint32_t pFreq2,
uint32_t pFreq3, uint32_t *pFreqOut)
@@ -811,7 +862,7 @@ HAL_Status HAL_CRU_SetPllPowerDown(struct PLL_SETUP *pSetup)
*/
uint32_t HAL_CRU_GetPllFreq(struct PLL_SETUP *pSetup)
{
- uint32_t refDiv, fbDiv, postdDv1, postDiv2, frac, dsmpd;
+ uint64_t refDiv, fbDiv, postdDv1, postDiv2, frac, dsmpd;
uint32_t mode = 0, rate = PLL_INPUT_OSC_RATE;
mode = PLL_GET_PLLMODE(READ_REG(*(pSetup->modeOffset)), pSetup->modeShift,
@@ -956,6 +1007,271 @@ HAL_Status HAL_CRU_SetPllPowerDown(struct PLL_SETUP *pSetup)
}
#endif
+#ifdef CRU_CLK_USE_CON_BANK
+static const struct HAL_CRU_DEV *CRU_GetInfo(void)
+{
+ return &g_cruDev;
+}
+
+HAL_Check HAL_CRU_ClkIsEnabled(uint32_t clk)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t index = CLK_GATE_GET_REG_OFFSET(clk);
+ uint32_t shift = CLK_GATE_GET_BITS_SHIFT(clk);
+ uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
+ uint32_t reg;
+ HAL_Check ret;
+
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].gateOffset + index * 4;
+ ret = (HAL_Check)(!((CRU_READ(reg) & (1 << shift)) >> shift));
+
+ return ret;
+}
+
+HAL_SECTION_SRAM_CODE
+HAL_Status HAL_CRU_ClkEnable(uint32_t clk)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t index = CLK_GATE_GET_REG_OFFSET(clk);
+ uint32_t shift = CLK_GATE_GET_BITS_SHIFT(clk);
+ uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
+ uint32_t reg;
+
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].gateOffset + index * 4;
+ CRU_WRITE(reg, shift, 1U << shift, 0U);
+
+ return HAL_OK;
+}
+
+HAL_Status HAL_CRU_ClkDisable(uint32_t clk)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t index = CLK_GATE_GET_REG_OFFSET(clk);
+ uint32_t shift = CLK_GATE_GET_BITS_SHIFT(clk);
+ uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
+ uint32_t reg;
+
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].gateOffset + index * 4;
+ CRU_WRITE(reg, shift, 1U << shift, 1U);
+
+ return HAL_OK;
+}
+
+HAL_Status HAL_CRU_ClkDisableUnused(uint32_t bank, uint32_t index, uint32_t val)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t reg;
+
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].gateOffset + index * 4;
+ CRU_WRITE(reg, 0, 0, val);
+
+ return HAL_OK;
+}
+
+HAL_Check HAL_CRU_ClkIsReset(uint32_t clk)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t index = CLK_GATE_GET_REG_OFFSET(clk);
+ uint32_t shift = CLK_GATE_GET_BITS_SHIFT(clk);
+ uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
+ uint32_t reg;
+ HAL_Check ret;
+
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].softOffset + index * 4;
+ ret = (HAL_Check)((CRU_READ(reg) & (1 << shift)) >> shift);
+
+ return ret;
+}
+
+HAL_Status HAL_CRU_ClkResetAssert(uint32_t clk)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t index = CLK_RESET_GET_REG_OFFSET(clk);
+ uint32_t shift = CLK_RESET_GET_BITS_SHIFT(clk);
+ uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
+ uint32_t reg;
+
+ HAL_ASSERT(shift < 16);
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].softOffset + index * 4;
+ CRU_WRITE(reg, shift, 1U << shift, 1U);
+
+ return HAL_OK;
+}
+
+HAL_Status HAL_CRU_ClkResetDeassert(uint32_t clk)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t index = CLK_RESET_GET_REG_OFFSET(clk);
+ uint32_t shift = CLK_RESET_GET_BITS_SHIFT(clk);
+ uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
+ uint32_t reg;
+
+ HAL_ASSERT(shift < 16);
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].softOffset + index * 4;
+ CRU_WRITE(reg, shift, 1U << shift, 0U);
+
+ return HAL_OK;
+}
+
+HAL_Status HAL_CRU_ClkResetSyncAssert(int numClks, uint32_t *clks)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t index = CLK_RESET_GET_REG_OFFSET(clks[0]);
+ uint32_t bank = CLK_GATE_GET_REG_BANK(clks[0]);
+ uint32_t val = 0;
+ uint32_t reg;
+ int i;
+
+ for (i = 0; i < numClks; i++) {
+ val |= HAL_BIT(CLK_RESET_GET_BITS_SHIFT(clks[i]));
+ if (index != CLK_RESET_GET_REG_OFFSET(clks[i])) {
+ return HAL_ERROR;
+ }
+ }
+
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].softOffset + index * 4;
+ CRU_WRITE(reg, 0, val, val);
+ HAL_DBG("%s: index: 0x%lx, val: 0x%lx\n", __func__, index, val);
+
+ return HAL_OK;
+}
+
+HAL_Status HAL_CRU_ClkResetSyncDeassert(int numClks, uint32_t *clks)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t index = CLK_RESET_GET_REG_OFFSET(clks[0]);
+ uint32_t bank = CLK_GATE_GET_REG_BANK(clks[0]);
+ uint32_t val = 0;
+ uint32_t reg;
+ int i;
+
+ for (i = 0; i < numClks; i++) {
+ val |= HAL_BIT(CLK_RESET_GET_BITS_SHIFT(clks[i]));
+ if (index != CLK_RESET_GET_REG_OFFSET(clks[i])) {
+ return HAL_ERROR;
+ }
+ }
+
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].softOffset + index * 4;
+ CRU_WRITE(reg, 0, val, 0);
+ HAL_DBG("%s: index: 0x%lx, val: 0x%lx\n", __func__, index, val);
+
+ return HAL_OK;
+}
+
+HAL_SECTION_SRAM_CODE
+HAL_Status HAL_CRU_ClkSetDiv(uint32_t divName, uint32_t divValue)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t shift, mask, index;
+ uint32_t reg, bank, maxDiv;
+
+ index = CLK_DIV_GET_REG_OFFSET(divName);
+ shift = CLK_DIV_GET_BITS_SHIFT(divName);
+ HAL_ASSERT(shift < 16);
+ mask = CLK_DIV_GET_MASK(divName);
+ maxDiv = CLK_DIV_GET_MAXDIV(divName) + 1;
+ if (divValue > maxDiv) {
+ divValue = maxDiv;
+ }
+
+ bank = CLK_DIV_GET_BANK(divName);
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
+ CRU_WRITE(reg, shift, mask, (divValue - 1U));
+
+ return HAL_OK;
+}
+
+uint32_t HAL_CRU_ClkGetDiv(uint32_t divName)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t shift, mask, index, divValue;
+ uint32_t reg, bank;
+
+ index = CLK_DIV_GET_REG_OFFSET(divName);
+ shift = CLK_DIV_GET_BITS_SHIFT(divName);
+ HAL_ASSERT(shift < 16);
+ mask = CLK_DIV_GET_MASK(divName);
+ bank = CLK_DIV_GET_BANK(divName);
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
+ divValue = ((CRU_READ(reg) & mask) >> shift) + 1;
+
+ return divValue;
+}
+
+HAL_SECTION_SRAM_CODE
+HAL_Status HAL_CRU_ClkSetMux(uint32_t muxName, uint32_t muxValue)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t shift, mask, index;
+ uint32_t reg, bank;
+
+ index = CLK_MUX_GET_REG_OFFSET(muxName);
+ shift = CLK_MUX_GET_BITS_SHIFT(muxName);
+ HAL_ASSERT(shift < 16);
+ mask = CLK_MUX_GET_MASK(muxName);
+ bank = CLK_MUX_GET_BANK(muxName);
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
+ CRU_WRITE(reg, shift, mask, muxValue);
+
+ return HAL_OK;
+}
+
+HAL_SECTION_SRAM_CODE
+uint32_t HAL_CRU_ClkGetMux(uint32_t muxName)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t shift, mask, index, muxValue;
+ uint32_t reg, bank;
+
+ index = CLK_MUX_GET_REG_OFFSET(muxName);
+ shift = CLK_MUX_GET_BITS_SHIFT(muxName);
+ HAL_ASSERT(shift < 16);
+ mask = CLK_MUX_GET_MASK(muxName);
+ bank = CLK_MUX_GET_BANK(muxName);
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
+ muxValue = ((CRU_READ(reg) & mask) >> shift);
+
+ return muxValue;
+}
+
+HAL_Status HAL_CRU_ClkSetFracDiv(uint32_t fracDivName,
+ uint32_t numerator,
+ uint32_t denominator)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t reg, bank;
+ uint32_t index;
+
+ index = CLK_DIV_GET_REG_OFFSET(fracDivName);
+ bank = CLK_DIV_GET_BANK(fracDivName);
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
+ CRU_WRITE(reg, 0, 0, ((numerator << 16) | denominator));
+
+ return HAL_OK;
+}
+
+HAL_Status HAL_CRU_ClkGetFracDiv(uint32_t fracDivName,
+ uint32_t *numerator,
+ uint32_t *denominator)
+{
+ const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
+ uint32_t reg, bank;
+ uint32_t index;
+ uint32_t val;
+
+ index = CLK_DIV_GET_REG_OFFSET(fracDivName);
+ bank = CLK_DIV_GET_BANK(fracDivName);
+ reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
+ val = CRU_READ(reg);
+
+ *numerator = (val & 0xffff0000) >> 16;
+ *denominator = (val & 0x0000ffff);
+
+ return HAL_OK;
+}
+#else /* CRU_CLK_USE_CON_BANK */
+
HAL_Check HAL_CRU_ClkIsEnabled(uint32_t clk)
{
uint32_t index = CLK_GATE_GET_REG_OFFSET(clk);
@@ -1153,16 +1469,18 @@ HAL_Status HAL_CRU_ClkResetSyncDeassert(int numClks, uint32_t *clks)
return HAL_OK;
}
+HAL_SECTION_SRAM_CODE
HAL_Status HAL_CRU_ClkSetDiv(uint32_t divName, uint32_t divValue)
{
- uint32_t shift, mask, index;
+ uint32_t shift, mask, index, maxDiv;
index = CLK_DIV_GET_REG_OFFSET(divName);
shift = CLK_DIV_GET_BITS_SHIFT(divName);
HAL_ASSERT(shift < 16);
mask = CLK_DIV_GET_MASK(divName);
- if (divValue > mask) {
- divValue = mask;
+ maxDiv = CLK_DIV_GET_MAXDIV(divName) + 1;
+ if (divValue > maxDiv) {
+ divValue = maxDiv;
}
#ifdef CRU_CLK_DIV_CON_CNT
@@ -1313,7 +1631,7 @@ HAL_Status HAL_CRU_ClkGetFracDiv(uint32_t fracDivName,
return HAL_OK;
}
-
+#endif /* CRU_CLK_USE_CON_BANK */
HAL_Status HAL_CRU_FracdivGetConfig(uint32_t rateOut, uint32_t rate,
uint32_t *numerator,
@@ -1340,6 +1658,31 @@ HAL_Status HAL_CRU_FracdivGetConfig(uint32_t rateOut, uint32_t rate,
return HAL_OK;
}
+HAL_Status HAL_CRU_FracdivGetConfigV2(uint32_t rateOut, uint32_t rate,
+ uint32_t *numerator,
+ uint32_t *denominator)
+{
+ uint32_t gcdVal;
+
+ gcdVal = CRU_Gcd(rate, rateOut);
+ if (!gcdVal) {
+ return HAL_ERROR;
+ }
+
+ *numerator = rateOut / gcdVal;
+ *denominator = rate / gcdVal;
+
+ if (*numerator < 4) {
+ *numerator *= 4;
+ *denominator *= 4;
+ }
+ if (*numerator > 0xffffff || *denominator > 0xffffff) {
+ return HAL_INVAL;
+ }
+
+ return HAL_OK;
+}
+
HAL_Status HAL_CRU_ClkNp5BestDiv(eCLOCK_Name clockName, uint32_t rate, uint32_t pRate, uint32_t *bestdiv)
{
uint32_t div = CLK_GET_DIV(clockName);
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_cru_rk3568.c b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_cru_rk3568.c
index 1653613a9..fc850a03d 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_cru_rk3568.c
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_cru_rk3568.c
@@ -874,6 +874,23 @@ uint32_t HAL_CRU_ClkGetFreq(eCLOCK_Name clockName)
}
return freq;
+ case CLK_SDMMC0:
+ if (HAL_CRU_ClkGetMux(clkMux) == 1) {
+ freq = 400000000;
+ } else if (HAL_CRU_ClkGetMux(clkMux) == 2) {
+ freq = 300000000;
+ } else if (HAL_CRU_ClkGetMux(clkMux) == 3) {
+ freq = 100000000;
+ } else if (HAL_CRU_ClkGetMux(clkMux) == 4) {
+ freq = 50000000;
+ } else if (HAL_CRU_ClkGetMux(clkMux) == 5) {
+ freq = 750000;
+ } else {
+ freq = PLL_INPUT_OSC_RATE;
+ }
+
+ return freq;
+
case ACLK_USB:
case HCLK_USB:
case PCLK_USB:
@@ -1002,6 +1019,22 @@ HAL_Status HAL_CRU_ClkSetFreq(eCLOCK_Name clockName, uint32_t rate)
mux = 0;
}
+ break;
+ case CLK_SDMMC0:
+ if (rate == 400000000) {
+ mux = 1;
+ } else if (rate == 750000) {
+ mux = 5;
+ } else if (rate == 50000000) {
+ mux = 4;
+ } else if (rate == 100000000) {
+ mux = 3;
+ } else if (rate == 300000000) {
+ mux = 2;
+ } else {
+ mux = 0;
+ }
+
break;
case ACLK_USB:
case HCLK_USB:
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_gmac.c b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_gmac.c
index f4fdeb357..9fc881f71 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_gmac.c
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_gmac.c
@@ -283,7 +283,9 @@
#define GMAC_DESC3_FD (0x1 << 29)
#define GMAC_DESC3_LD (0x1 << 28)
#define GMAC_DESC3_BUF1V (0x1 << 24)
+#define GMAC_DESC3_CIC (0x3 << 16)
+#define DES3_ERROR_SUMMARY (1 << 15)
#define DES3_ERROR_SUMMARY (1 << 15)
/* Generic MII registers. */
@@ -1123,7 +1125,7 @@ int32_t HAL_GMAC_MDIORead(struct GMAC_HANDLE *pGMAC, int32_t mdioAddr,
HAL_ASSERT(pGMAC != NULL);
- HAL_DBG("Mdio Read addr=%ld, reg=%ld\n", mdioAddr, mdioReg);
+ // HAL_DBG("Mdio Read addr=%ld, reg=%ld\n", mdioAddr, mdioReg);
status = Mdio_WaitIdle(pGMAC);
if (status) {
HAL_DBG("MDIO not idle at entry");
@@ -1173,8 +1175,8 @@ HAL_Status HAL_GMAC_MDIOWrite(struct GMAC_HANDLE *pGMAC, int32_t mdioAddr,
HAL_ASSERT(pGMAC != NULL);
- HAL_DBG("%s(addr=%lx, reg=%ld, val=%x):\n", __func__,
- mdioAddr, mdioReg, mdioVal);
+ // HAL_DBG("%s(addr=%lx, reg=%ld, val=%x):\n", __func__,
+ // mdioAddr, mdioReg, mdioVal);
status = Mdio_WaitIdle(pGMAC);
if (status) {
HAL_DBG("MDIO not idle at entry");
@@ -1347,7 +1349,6 @@ HAL_Status HAL_GMAC_PHYParseLink(struct GMAC_HANDLE *pGMAC)
if (pGMAC->phyStatus.neg == PHY_AUTONEG_ENABLE) {
uint32_t lpa = 0, estatus = 0;
int32_t gblpa = 0;
-
/* Check for gigabit capability */
if (pGMAC->phyStatus.supported & (HAL_GMAC_PHY_SUPPORTED_1000baseT_Full |
HAL_GMAC_PHY_SUPPORTED_1000baseT_Half)) {
@@ -1746,6 +1747,13 @@ HAL_Status HAL_GMAC_AdjustLink(struct GMAC_HANDLE *pGMAC, int32_t txDelay,
*
* @return HAL status
*/
+#define GENMASK(h, l) (((1U << ((h) - (l) + 1)) - 1) << (l))
+#define DMA_AXI_WR_OSR_LMT GENMASK(27, 24)
+#define DMA_AXI_WR_OSR_LMT_SHIFT 24
+#define DMA_AXI_RD_OSR_LMT GENMASK(19, 16)
+#define DMA_AXI_RD_OSR_LMT_SHIFT 16
+#define DMA_AXI_OSR_MAX 0xf
+
HAL_Status HAL_GMAC_Start(struct GMAC_HANDLE *pGMAC, uint8_t *addr)
{
uint32_t mmc_mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
@@ -1764,6 +1772,7 @@ HAL_Status HAL_GMAC_Start(struct GMAC_HANDLE *pGMAC, uint8_t *addr)
value = READ_REG(pGMAC->pReg->DMA_MODE);
WRITE_REG(pGMAC->pReg->DMA_MODE, value | DMA_MODE_SWR);
/* Wait for software Reset */
+ HAL_DelayMs(100);
while (limit--) {
if (!(READ_REG(pGMAC->pReg->DMA_MODE) & DMA_MODE_SWR)) {
break;
@@ -1777,10 +1786,16 @@ HAL_Status HAL_GMAC_Start(struct GMAC_HANDLE *pGMAC, uint8_t *addr)
}
HAL_DelayMs(100);
+ value = READ_REG(pGMAC->pReg->DMA_SYSBUS_MODE);
+ value &= ~DMA_AXI_WR_OSR_LMT;
+ value |= (0x0 & DMA_AXI_OSR_MAX) << DMA_AXI_WR_OSR_LMT_SHIFT;
+
+ value &= ~DMA_AXI_RD_OSR_LMT;
+ value |= (0x2 & DMA_AXI_OSR_MAX) << DMA_AXI_RD_OSR_LMT_SHIFT;
/* DMA init */
- WRITE_REG(pGMAC->pReg->DMA_SYSBUS_MODE, DMA_SYSBUS_MODE_BLEN16 |
- DMA_SYSBUS_MODE_BLEN8 | DMA_SYSBUS_MODE_BLEN4 | 1 << 12 | 1 << 14);
+ WRITE_REG(pGMAC->pReg->DMA_SYSBUS_MODE, value | DMA_SYSBUS_MODE_BLEN16 |
+ DMA_SYSBUS_MODE_BLEN8 | DMA_SYSBUS_MODE_BLEN4);
/* Mask interrupts by writing to CSR7 */
WRITE_REG(pGMAC->pReg->DMA_CH0_INTERRUPT_ENABLE, DMA_CHAN_INTR_DEFAULT_MASK);
@@ -1789,6 +1804,7 @@ HAL_Status HAL_GMAC_Start(struct GMAC_HANDLE *pGMAC, uint8_t *addr)
/* Set the HW DMA mode and the COE */
txFifosz = 128 << ((hwCap & GMAC_HW_TXFIFOSIZE) >> GMAC_HW_TXFIFOSIZE_SHIFT);
rxFifosz = 128 << ((hwCap & GMAC_HW_RXFIFOSIZE) >> GMAC_HW_RXFIFOSIZE_SHIFT);
+
/* init rx chan */
value = READ_REG(pGMAC->pReg->DMA_CH0_RX_CONTROL);
@@ -1800,9 +1816,13 @@ HAL_Status HAL_GMAC_Start(struct GMAC_HANDLE *pGMAC, uint8_t *addr)
WRITE_REG(pGMAC->pReg->DMA_CH0_RXDESC_TAIL_POINTER,
(uint32_t)(uint64_t)(pGMAC->rxDescs_dma + pGMAC->rxSize));
+ value = READ_REG(pGMAC->pReg->DMA_CH0_CONTROL);
+ value = value | 1 << 16;
+ WRITE_REG(pGMAC->pReg->DMA_CH0_CONTROL, value);
+
/* init tx chan */
value = READ_REG(pGMAC->pReg->DMA_CH0_TX_CONTROL);
- value = value | (8 << DMA_CH0_TX_CONTROL_TXPBL_SHIFT);
+ value = value | (32 << DMA_CH0_TX_CONTROL_TXPBL_SHIFT);
value |= DMA_CH0_TX_CONTROL_OSF;
WRITE_REG(pGMAC->pReg->DMA_CH0_TX_CONTROL, value);
@@ -2002,7 +2022,7 @@ HAL_Status HAL_GMAC_Send(struct GMAC_HANDLE *pGMAC, void *packet,
desc->des0 = (uint32_t)(uint64_t)packet;
desc->des1 = 0;
- desc->des2 = length;
+ desc->des2 = length | 1<<31;
/*
* Make sure that if HW sees the _OWN write below, it will see all the
* writes to the rest of the descriptor too.
@@ -2046,10 +2066,9 @@ uint8_t *HAL_GMAC_Recv(struct GMAC_HANDLE *pGMAC, int32_t *length)
*length = 0;
desc = pGMAC->rxDescs + pGMAC->rxDescIdx;
- HAL_DBG("Rx at %p\n", desc->des0);
des3 = desc->des3;
if (des3 & GMAC_DESC3_OWN) {
- HAL_DBG("%s: RX packet not available\n", __func__);
+ HAL_DBG("%p: RX packet not available\n", desc->des0);
return NULL;
}
@@ -2106,10 +2125,9 @@ void HAL_GMAC_CleanRX(struct GMAC_HANDLE *pGMAC)
desc->des1 = 0;
desc->des2 = 0;
desc->des3 = GMAC_DESC3_OWN | GMAC_DESC3_BUF1V | GMAC_DESC3_IOC;
- HAL_DBG("Clean buff %p\n", desc->des0);
- desc_dma = pGMAC->rxDescs_dma + pGMAC->rxDescIdx;
- HAL_DBG("Clean desc %p\n", desc_dma);
- WRITE_REG(pGMAC->pReg->DMA_CH0_RXDESC_TAIL_POINTER, (uint32_t)(uint64_t)desc_dma);
+
+ WRITE_REG(pGMAC->pReg->DMA_CH0_RXDESC_TAIL_POINTER,
+ (uint32_t)(uint64_t)(pGMAC->rxDescs_dma + pGMAC->rxDescIdx));
pGMAC->rxDescIdx++;
pGMAC->rxDescIdx %= pGMAC->rxSize;
@@ -2172,7 +2190,6 @@ HAL_Status HAL_GMAC_Init(struct GMAC_HANDLE *pGMAC, struct GMAC_REG *pReg,
pGMAC->txDescIdx = 0;
pGMAC->rxDescIdx = 0;
-
/* Get CR bits depending on hclk value */
if ((freq >= 20000000) && (freq < 35000000)) {
/* CSR Clock Range between 20-35 MHz */
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_gpio.c b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_gpio.c
index 5583b62bc..da75ea17e 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_gpio.c
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/hal_gpio.c
@@ -58,7 +58,7 @@
*/
static void GPIO_SetEOI(struct GPIO_REG *pGPIO, ePINCTRL_GPIO_PINS pin)
{
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
if (IS_GPIO_HIGH_PIN(pin)) {
pin &= 0xFFFF0000;
pGPIO->PORT_EOI_H = pin | (pin >> 16);
@@ -82,7 +82,7 @@ static uint32_t GPIO_GetIntType(struct GPIO_REG *pGPIO)
{
uint32_t type;
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
type = (pGPIO->INT_TYPE_L & 0xffff);
type |= ((pGPIO->INT_TYPE_H & 0xffff) << 16);
type |= (pGPIO->INT_BOTHEDGE_L & 0xffff);
@@ -161,7 +161,7 @@ HAL_Status HAL_GPIO_SetIntType(struct GPIO_REG *pGPIO, ePINCTRL_GPIO_PINS pin, e
return HAL_INVAL;
}
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
if (IS_GPIO_HIGH_PIN(pin)) {
pin &= 0xFFFF0000;
pGPIO->INT_TYPE_H = (type) ? (pin | (pin >> 16)) : (pin);
@@ -195,7 +195,7 @@ HAL_Status HAL_GPIO_SetIntType(struct GPIO_REG *pGPIO, ePINCTRL_GPIO_PINS pin, e
*/
HAL_Status HAL_GPIO_SetPinDirection(struct GPIO_REG *pGPIO, ePINCTRL_GPIO_PINS pin, eGPIO_pinDirection direction)
{
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
if (IS_GPIO_HIGH_PIN(pin)) {
pin &= 0xFFFF0000;
pGPIO->SWPORT_DDR_H = (direction == GPIO_OUT) ? (pin | (pin >> 16)) : (pin);
@@ -251,7 +251,7 @@ eGPIO_pinDirection HAL_GPIO_GetPinDirection(struct GPIO_REG *pGPIO, ePINCTRL_GPI
eGPIO_pinDirection direction;
uint32_t value;
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
value = IS_GPIO_HIGH_PIN(pin) ? (pGPIO->SWPORT_DDR_H & (pin >> 16)) : (pGPIO->SWPORT_DDR_L & pin);
#else
value = pGPIO->SWPORTA_DDR & pin;
@@ -275,7 +275,7 @@ eGPIO_pinDirection HAL_GPIO_GetPinDirection(struct GPIO_REG *pGPIO, ePINCTRL_GPI
*/
HAL_Status HAL_GPIO_SetPinLevel(struct GPIO_REG *pGPIO, ePINCTRL_GPIO_PINS pin, eGPIO_pinLevel level)
{
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
if (IS_GPIO_HIGH_PIN(pin)) {
pin &= 0xFFFF0000;
pGPIO->SWPORT_DR_H = (level == GPIO_HIGH) ? (pin | (pin >> 16)) : (pin);
@@ -340,7 +340,7 @@ eGPIO_pinLevel HAL_GPIO_GetPinData(struct GPIO_REG *pGPIO, ePINCTRL_GPIO_PINS pi
eGPIO_pinLevel level;
uint32_t value;
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
value = IS_GPIO_HIGH_PIN(pin) ? (pGPIO->SWPORT_DR_H & (pin >> 16)) : (pGPIO->SWPORT_DR_L & pin);
#else
value = pGPIO->SWPORTA_DR & pin;
@@ -365,7 +365,7 @@ eGPIO_pinLevel HAL_GPIO_GetPinLevel(struct GPIO_REG *pGPIO, ePINCTRL_GPIO_PINS p
{
uint32_t value;
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
value = (pGPIO->EXT_PORT & pin);
#else
value = (pGPIO->EXT_PORTA & pin);
@@ -383,7 +383,7 @@ uint32_t HAL_GPIO_GetBankLevel(struct GPIO_REG *pGPIO)
{
uint32_t value;
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
value = (pGPIO->EXT_PORT);
#else
value = (pGPIO->EXT_PORTA);
@@ -404,7 +404,7 @@ uint32_t HAL_GPIO_GetBankLevel(struct GPIO_REG *pGPIO)
*/
void HAL_GPIO_EnableIRQ(struct GPIO_REG *pGPIO, ePINCTRL_GPIO_PINS pin)
{
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
if (IS_GPIO_HIGH_PIN(pin)) {
pin &= 0xFFFF0000;
#ifndef HAL_GPIO_IRQ_GROUP_MODULE_ENABLED
@@ -433,7 +433,7 @@ void HAL_GPIO_EnableIRQ(struct GPIO_REG *pGPIO, ePINCTRL_GPIO_PINS pin)
*/
void HAL_GPIO_DisableIRQ(struct GPIO_REG *pGPIO, ePINCTRL_GPIO_PINS pin)
{
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
if (IS_GPIO_HIGH_PIN(pin)) {
pin &= 0xFFFF0000;
pGPIO->INT_EN_H = pin;
@@ -511,7 +511,7 @@ void HAL_GPIO_IRQHandler(struct GPIO_REG *pGPIO, eGPIO_bankId bank)
*/
HAL_Status HAL_GPIO_EnableVirtualModel(struct GPIO_REG *pGPIO)
{
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
pGPIO->GPIO_VIRTUAL_EN = 0x10001;
return HAL_OK;
@@ -527,7 +527,7 @@ HAL_Status HAL_GPIO_EnableVirtualModel(struct GPIO_REG *pGPIO)
*/
HAL_Status HAL_GPIO_DisableVirtualModel(struct GPIO_REG *pGPIO)
{
-#if (GPIO_VER_ID == 0x01000C2BU)
+#if (GPIO_VER_ID >= 0x01000C2BU)
pGPIO->GPIO_VIRTUAL_EN = 0x10000;
return HAL_OK;
@@ -545,22 +545,51 @@ HAL_Status HAL_GPIO_DisableVirtualModel(struct GPIO_REG *pGPIO)
*/
HAL_Status HAL_GPIO_SetVirtualModel(struct GPIO_REG *pGPIO, ePINCTRL_GPIO_PINS pin, eGPIO_VirtualModel vmodel)
{
-#if (GPIO_VER_ID == 0x01000C2BU)
- uint32_t low_pins, high_pins;
+#if (GPIO_VER_ID >= 0x01000C2BU)
+ uint32_t lowPins, highPins;
- low_pins = pin & 0x0000ffff;
- high_pins = (pin & 0xffff0000) >> 16;
+ lowPins = pin & 0x0000ffff;
+ highPins = (pin & 0xffff0000) >> 16;
+#if defined(GPIO0_EXP)
/* Support OS_A and OS_B */
if (vmodel == GPIO_VIRTUAL_MODEL_OS_B) {
- pGPIO->GPIO_REG_GROUP_L = low_pins << 16;
- pGPIO->GPIO_REG_GROUP_H = high_pins << 16;
+ pGPIO->GPIO_REG_GROUP_L = lowPins << 16;
+ pGPIO->GPIO_REG_GROUP_H = highPins << 16;
} else {
- pGPIO->GPIO_REG_GROUP_L = low_pins | (low_pins << 16);
- pGPIO->GPIO_REG_GROUP_H = high_pins | (high_pins << 16);
+ pGPIO->GPIO_REG_GROUP_L = lowPins | (lowPins << 16);
+ pGPIO->GPIO_REG_GROUP_H = highPins | (highPins << 16);
}
return HAL_OK;
+#elif defined(GPIO0_EXP3)
+ /* Support 4 OS */
+ switch (vmodel) {
+ case GPIO_VIRTUAL_MODEL_OS_A:
+ pGPIO->GPIO_REG_GROUP_L = lowPins | (lowPins << 16);
+ pGPIO->GPIO_REG_GROUP_H = highPins | (highPins << 16);
+ break;
+ case GPIO_VIRTUAL_MODEL_OS_B:
+ pGPIO->GPIO_REG_GROUP1_L = lowPins | (lowPins << 16);
+ pGPIO->GPIO_REG_GROUP1_H = highPins | (highPins << 16);
+ break;
+ case GPIO_VIRTUAL_MODEL_OS_C:
+ pGPIO->GPIO_REG_GROUP2_L = lowPins | (lowPins << 16);
+ pGPIO->GPIO_REG_GROUP2_H = highPins | (highPins << 16);
+ break;
+ case GPIO_VIRTUAL_MODEL_OS_D:
+ pGPIO->GPIO_REG_GROUP3_L = lowPins | (lowPins << 16);
+ pGPIO->GPIO_REG_GROUP3_H = highPins | (highPins << 16);
+ break;
+ default:
+ HAL_DBG("unknown gpio virtual model-%d\n", vmodel);
+ break;
+ }
+
+ return HAL_OK;
+#else
+#error missing GPIO EXP register definition!
+#endif
#endif
return HAL_ERROR;
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/test_gmac.c b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/test_gmac.c
index 35d9bb0fa..6edd00727 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/test_gmac.c
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/hal/test_gmac.c
@@ -85,7 +85,7 @@ struct GMAC_ETH_CONFIG {
/********************* Private Variable Definition ***************************/
-static uint8_t dstAddr[6] = { 0x00, 0x0C, 0x29, 0xf8, 0x7a, 0x6b };
+static uint8_t dstAddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#if defined(HAL_GMAC_MODULE_ENABLED) && defined(SOC_RK3568)
static struct GMAC_ETH_CONFIG ethConfigTable[] =
@@ -349,7 +349,6 @@ static void *malloc_align(size_t size, size_t align, uintptr_t va, uintptr_t *pa
/* get total aligned size */
align_size = ((size + 0x03) & ~0x03);
/* allocate memory block from heap */
- HAL_DBG("size: %d, align:%d\n",align_size, align);
// ptr = malloc(align_size);
if (naive_mmap(&va, pa, align_size, true) < 0){
@@ -417,7 +416,7 @@ static HAL_Status GMAC_Send_Test(struct GMAC_ETH_CONFIG *eth, struct GMAC_HANDLE
}
/* dump packages */
- // Dump_Hex("Tx", ptr, len);
+ Dump_Hex("Tx", ptr, len);
// HAL_DCACHE_CleanByRange((uint64_t)ptr, len);
uint8_t * ptr_dma = (uint8_t *)HAL_GMAC_GetTXBufferDMA(pGMAC);
@@ -426,7 +425,6 @@ static HAL_Status GMAC_Send_Test(struct GMAC_ETH_CONFIG *eth, struct GMAC_HANDLE
printf("GMAC send failed: %d\n", status);
}
- print_desc(pGMAC);
return status;
}
@@ -444,7 +442,6 @@ static uint16_t GMAC_Recv_Test(struct GMAC_HANDLE *pGMAC)
status = GMAC_ETH_IRQ(pGMAC);
ptr = HAL_GMAC_Recv(pGMAC, &size);
while (status && ptr) {
- print_desc(pGMAC);
if (size > 0 && ptr) {
/* dump packages */
Dump_Hex("Rx", ptr, size);
@@ -462,20 +459,21 @@ static uint16_t GMAC_Recv_Test(struct GMAC_HANDLE *pGMAC)
static HAL_Status GMAC_Memory_Init(struct GMAC_ETH_CONFIG *eth, struct GMAC_HANDLE *pGMAC)
{
- uintptr_t rx_va = 0x1000000000, rx_pa = 0;
- if (naive_mmap(&rx_va, &rx_pa, GMAC_DESC_RX_SIZE, true) < 0){
- HAL_DBG("RX Desc alloc failed\n");
- }
- eth->rxDescs = (struct GMAC_Desc *)0x1000000000;
- eth->rxDescs_dma = (struct GMAC_Desc *)rx_pa;
- uintptr_t tx_va = 0x1000400000, tx_pa = 0;
+ uintptr_t tx_va = 0x1000000000, tx_pa = 0;
if (naive_mmap(&tx_va, &tx_pa, GMAC_DESC_TX_SIZE, true) < 0){
HAL_DBG("TX Desc alloc failed\n");
}
- eth->txDescs = (struct GMAC_Desc *)0x1000400000;
+ eth->txDescs = (struct GMAC_Desc *)0x1000000000;
eth->txDescs_dma = (struct GMAC_Desc *)tx_pa;
+ uintptr_t rx_va = 0x1000400000, rx_pa = 0;
+ if (naive_mmap(&rx_va, &rx_pa, GMAC_DESC_RX_SIZE, true) < 0){
+ HAL_DBG("RX Desc alloc failed\n");
+ }
+ eth->rxDescs = (struct GMAC_Desc *)0x1000400000;
+ eth->rxDescs_dma = (struct GMAC_Desc *)rx_pa;
+
if (!eth->rxDescs || !eth->txDescs_dma ||
!eth->txDescs || !eth->txDescs_dma){
return -1;
@@ -484,14 +482,16 @@ static HAL_Status GMAC_Memory_Init(struct GMAC_ETH_CONFIG *eth, struct GMAC_HAND
HAL_DBG("rx:%p, %p\n",eth->rxDescs, eth->rxDescs_dma);
HAL_DBG("tx:%p, %p\n",eth->txDescs, eth->txDescs_dma);
- uintptr_t rxbuf_va = 0x1000800000, rxbuf_pa = 0;
- uintptr_t txbuf_va = 0x1000C00000, txbuf_pa = 0;
- eth->rxBuff = malloc_align(GMAC_RX_BUFFER_SIZE, ARCH_DMA_MINALIGN, rxbuf_va, &rxbuf_pa);
- eth->rxBuff = (void *)0x1000800000;
- eth->rxBuff_dma = (void *)rxbuf_pa;
+
+ uintptr_t txbuf_va = 0x1000800000, txbuf_pa = 0;
eth->txBuff = malloc_align(GMAC_TX_BUFFER_SIZE, ARCH_DMA_MINALIGN, txbuf_va, &txbuf_pa);
- eth->txBuff = (void *)0x1000C00000;
+ eth->txBuff = (void *)0x1000800000;
eth->txBuff_dma = (void *)txbuf_pa;
+
+ uintptr_t rxbuf_va = 0x1000c00000, rxbuf_pa = 0;
+ eth->rxBuff = malloc_align(GMAC_RX_BUFFER_SIZE, ARCH_DMA_MINALIGN, rxbuf_va, &rxbuf_pa);
+ eth->rxBuff = (void *)0x1000c00000;
+ eth->rxBuff_dma = (void *)rxbuf_pa;
if (!eth->rxBuff || !eth->txBuff ||
!eth->rxBuff_dma || !eth->txBuff_dma){
@@ -499,8 +499,6 @@ static HAL_Status GMAC_Memory_Init(struct GMAC_ETH_CONFIG *eth, struct GMAC_HAND
}
HAL_DBG("rx_buff:%p,%p\n",eth->rxBuff, eth->rxBuff_dma);
HAL_DBG("tx_buff:%p,%p,\n",eth->txBuff, eth->txBuff_dma);
- HAL_DBG("GMAC_DESC_RX_SIZE:%d\n", GMAC_DESC_RX_SIZE);
- HAL_DBG("GMAC_RX_BUFFER_SIZE:%d\n", GMAC_RX_BUFFER_SIZE);
memset(eth->rxDescs, 0, GMAC_DESC_RX_SIZE);
memset(eth->txDescs, 0, GMAC_DESC_TX_SIZE);
memset(eth->rxBuff, 0, GMAC_RX_BUFFER_SIZE);
@@ -540,9 +538,9 @@ static HAL_Status GMAC_Init(uint8_t id)
interface = eth->mode;
if (interface == PHY_INTERFACE_MODE_RGMII) {
- HAL_CRU_ClkSetFreq(gmacDev->clkID, 125000000);
+ HAL_CRU_ClkSetFreq(gmacDev->clkID125M, 125000000);
} else {
- HAL_CRU_ClkSetFreq(gmacDev->clkID, 50000000);
+ HAL_CRU_ClkSetFreq(gmacDev->clkID50M, 50000000);
}
freq = HAL_CRU_ClkGetFreq(gmacDev->pclkID);
@@ -583,7 +581,6 @@ static void GMAC0_Iomux_Config(void)
GPIO_PIN_B6, /* gmac0_rxd0 */
PIN_CONFIG_MUX_FUNC1);
HAL_PINCTRL_SetIOMUX(GPIO_BANK2,
- GPIO_PIN_C0 | ///* eth0_refclko25m */
GPIO_PIN_C3 | /* gmac0_mdc */
GPIO_PIN_C4 | /* gmac0_mdio */
GPIO_PIN_C0 | /* gmac0_rxdvcrs */
@@ -646,19 +643,19 @@ int main() {
} else {
return -1;
}
- HAL_DBG("map GMAC0\n");
+
if (!mmap(0x2000000000ULL+ GMAC0_BASE, GMAC0_BASE, 0x10000, true)) {
printf("eth_hal: mmap GMAC0(%8x) failed\n", GMAC0);
exit(1);
}
- HAL_DBG("map GPIO2\n");
+
if (!mmap(0x2000000000ULL + GPIO2_BASE, GPIO2_BASE, 0x10000, true)) {
printf("eth_hal: mmap GPIO2(%8x) failed\n", GPIO2);
exit(1);
}
- HAL_DBG("map GPIO3\n");
+
if (!mmap(0x2000000000ULL + GPIO3_BASE, GPIO3_BASE, 0x10000, true)) {
- printf("eth_hal: mmap GPIO2(%8x) failed\n", GPIO2);
+ printf("eth_hal: mmap GPIO3(%8x) failed\n", GPIO3);
exit(1);
}
@@ -668,65 +665,69 @@ int main() {
}
if (!mmap(0x2000000000ULL + CRU_BASE, CRU_BASE, 0x10000, true)) {
- printf("eth_hal: mmap GRF(%8x) failed\n", GRF);
+ printf("eth_hal: mmap CRU(%8x) failed\n", CRU);
exit(1);
}
- if (!mmap(0x2000000000ULL + TIMER5_BASE, CRU_BASE, 32, true)) {
- printf("eth_hal: mmap GRF(%8x) failed\n", GRF);
+ if (!mmap(0x2000000000ULL + TIMER5_BASE, TIMER5_BASE, 32, true)) {
+ printf("eth_hal: mmap TIMER5(%8x) failed\n", TIMER5);
exit(1);
}
if (!mmap(0x2000000000ULL + PMUCRU_BASE, PMUCRU_BASE, 0x10000, true)) {
- printf("eth_hal: mmap GRF(%8x) failed\n", GRF);
+ printf("eth_hal: mmap PMUCRU(%8x) failed\n", PMUCRU);
exit(1);
}
- HAL_DBG("config iomux\n");
+ HAL_TIMER_SysTimerInit(TIMER5);
+
/* ionmux */
GMAC_Iomux_Config(bus);
- HAL_DBG("config cru\n");
HAL_CRU_ClkEnable(eth->halDev->pclkGateID);
- HAL_CRU_ClkEnable(eth->halDev->clkGateID);
+ HAL_CRU_ClkEnable(eth->halDev->clkGateID125M);
+ HAL_CRU_ClkEnable(eth->halDev->clkGateID50M);
/* Register irq */
// register_irq(eth->halDev->irqNum, );
/* PHY reset */
- HAL_DBG("reset phy\n");
GMAC_PHY_Reset(eth);
/* GMAC Init */
- HAL_DBG("init gmac\n");
GMAC_Init(bus);
- HAL_DBG("init memory\n");
GMAC_Memory_Init(eth, pGMAC);
/* Enable GMAC and DMA transmission and reception */
- HAL_DBG("start gmac\n");
HAL_GMAC_Start(pGMAC, eth->macAddr);
- // print_desc(pGMAC);
+
/* Update links information */
- HAL_DBG("phy update link\n");
PHY_Update_Links(eth, pGMAC, bus);
- // print_desc(pGMAC);
+
/* Dump MAC Regs */
Dump_Regs(pGMAC);
+
/* Dump PHY Regs */
// PHY_Dump(eth, pGMAC);
- HAL_DBG("Init Down\n");
for (i = 0; i < GMAC_TEST_TIMES; i++) {
- HAL_DBG("TEST Send %d\n", i);
+ HAL_DBG("TEST %d\n", i);
+
/* GMAC Send 64 bytes */
- // GMAC_Send_Test(eth, pGMAC, 64);
- /* GMAC Send 1500 bytes */
- GMAC_Send_Test(eth, pGMAC, 1500);
+ HAL_DBG("--------------GMAC_Send_Test START!--------------\n");
+ GMAC_Send_Test(eth, pGMAC, 64);
+ HAL_DBG("--------------GMAC_Send_Test END!--------------\n");
+
HAL_DelayMs(1000);
- HAL_DBG("TEST Recv %d\n", i);
+ print_desc(pGMAC);
+
/* GMAC Recv */
+ HAL_DBG("--------------GMAC_Recv_Test START! -------------- \n");
GMAC_Recv_Test(pGMAC);
+ HAL_DBG("--------------GMAC_Recv_Test END!!-------------- \n");
+
+ HAL_DelayMs(1000);
+ Dump_Regs(pGMAC);
}
- Dump_Regs(pGMAC);
HAL_CRU_ClkDisable(eth->halDev->pclkGateID);
- HAL_CRU_ClkDisable(eth->halDev->clkGateID);
+ HAL_CRU_ClkDisable(eth->halDev->clkGateID125M);
+ HAL_CRU_ClkDisable(eth->halDev->clkGateID50M);
// free_align(eth->txBuff);
// free_align(eth->rxBuff);
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_cru.h b/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_cru.h
index b22809b81..95b309f91 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_cru.h
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_cru.h
@@ -159,6 +159,11 @@ typedef enum {
GLB_RST_SND_WDT1,
GLB_RST_FST_WDT2,
GLB_RST_SND_WDT2,
+ GLB_RST_FST_WDT3,
+ GLB_RST_SND_WDT3,
+ GLB_RST_FST_WDT4,
+ GLB_RST_SND_WDT4,
+
} eCRU_WdtRstType;
struct CRU_BANK_INFO {
@@ -192,12 +197,14 @@ int HAL_CRU_FreqGetMux4(uint32_t freq, uint32_t freq0, uint32_t freq1,
int HAL_CRU_FreqGetMux3(uint32_t freq, uint32_t freq0, uint32_t freq1,
uint32_t freq2);
int HAL_CRU_FreqGetMux2(uint32_t freq, uint32_t freq0, uint32_t freq1);
+int HAL_CRU_FreqGetMuxArray(uint32_t freq, uint32_t *table, int num);
uint32_t HAL_CRU_MuxGetFreq4(uint32_t muxName, uint32_t freq0, uint32_t freq1,
uint32_t freq2, uint32_t freq3);
uint32_t HAL_CRU_MuxGetFreq3(uint32_t muxName, uint32_t freq0, uint32_t freq1,
uint32_t freq2);
uint32_t HAL_CRU_MuxGetFreq2(uint32_t muxName, uint32_t freq0, uint32_t freq1);
+uint32_t HAL_CRU_MuxGetFreqArray(uint32_t muxName, uint32_t *table, int num);
int HAL_CRU_RoundFreqGetMux4(uint32_t freq, uint32_t pFreq0, uint32_t pFreq1,
uint32_t pFreq2, uint32_t pFreq3, uint32_t *pFreqOut);
@@ -205,6 +212,7 @@ int HAL_CRU_RoundFreqGetMux3(uint32_t freq, uint32_t pFreq0, uint32_t pFreq1,
uint32_t pFreq2, uint32_t *pFreqOut);
int HAL_CRU_RoundFreqGetMux2(uint32_t freq, uint32_t pFreq0, uint32_t pFreq1,
uint32_t *pFreqOut);
+int HAL_CRU_RoundFreqGetMuxArray(uint32_t freq, uint32_t *table, int num, uint32_t *pFreqOut, bool is_div);
/** @} */
@@ -371,6 +379,21 @@ uint32_t HAL_CRU_ClkGetMux(uint32_t muxName);
HAL_Status HAL_CRU_FracdivGetConfig(uint32_t rateOut, uint32_t rate,
uint32_t *numerator,
uint32_t *denominator);
+
+
+/**
+ * @brief Get frac div config V2(24bit).
+ * @param rateOut: clk out rate.
+ * @param rate: clk src rate.
+ * @param numerator: the returned numerator.
+ * @param denominator: the returned denominator.
+ * @return HAL_Status.
+ */
+HAL_Status HAL_CRU_FracdivGetConfigV2(uint32_t rateOut, uint32_t rate,
+ uint32_t *numerator,
+ uint32_t *denominator);
+
+
/**
* @brief Get clk freq.
* @param clockName: CLOCK_Name id.
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_gmac.h b/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_gmac.h
index 5f6c731e4..de369dd03 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_gmac.h
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_gmac.h
@@ -207,10 +207,10 @@ struct GMAC_Link {
* @brief GMAC DMA Descriptors Data Structure Definition
*/
struct GMAC_Desc {
- uint32_t des0; /**< DMA Descriptors first word */
- uint32_t des1; /**< DMA Descriptors second word */
- uint32_t des2; /**< DMA Descriptors third word */
- uint32_t des3; /**< DMA Descriptors four word */
+ volatile uint32_t des0; /**< DMA Descriptors first word */
+ volatile uint32_t des1; /**< DMA Descriptors second word */
+ volatile uint32_t des2; /**< DMA Descriptors third word */
+ volatile uint32_t des3; /**< DMA Descriptors four word */
};
/**
@@ -287,8 +287,10 @@ struct GMAC_HANDLE {
*/
struct HAL_GMAC_DEV {
struct GMAC_REG *pReg;
- eCLOCK_Name clkID;
- uint32_t clkGateID;
+ eCLOCK_Name clkID125M;
+ eCLOCK_Name clkID50M;
+ uint32_t clkGateID125M;
+ uint32_t clkGateID50M;
eCLOCK_Name pclkID;
uint32_t pclkGateID;
IRQn_Type irqNum;
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_pinctrl.h b/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_pinctrl.h
index 10e852ca0..ed07eab61 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_pinctrl.h
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/hal_pinctrl.h
@@ -370,6 +370,516 @@ typedef enum {
GPIO4_EXP_D5,
GPIO4_EXP_D6,
GPIO4_EXP_D7,
+#endif
+#if defined(GPIO0_EXP1)
+ GPIO0_EXP1_A0 = 160,
+ GPIO0_EXP1_A1,
+ GPIO0_EXP1_A2,
+ GPIO0_EXP1_A3,
+ GPIO0_EXP1_A4,
+ GPIO0_EXP1_A5,
+ GPIO0_EXP1_A6,
+ GPIO0_EXP1_A7,
+ GPIO0_EXP1_B0 = 168,
+ GPIO0_EXP1_B1,
+ GPIO0_EXP1_B2,
+ GPIO0_EXP1_B3,
+ GPIO0_EXP1_B4,
+ GPIO0_EXP1_B5,
+ GPIO0_EXP1_B6,
+ GPIO0_EXP1_B7,
+ GPIO0_EXP1_C0 = 176,
+ GPIO0_EXP1_C1,
+ GPIO0_EXP1_C2,
+ GPIO0_EXP1_C3,
+ GPIO0_EXP1_C4,
+ GPIO0_EXP1_C5,
+ GPIO0_EXP1_C6,
+ GPIO0_EXP1_C7,
+ GPIO0_EXP1_D0 = 184,
+ GPIO0_EXP1_D1,
+ GPIO0_EXP1_D2,
+ GPIO0_EXP1_D3,
+ GPIO0_EXP1_D4,
+ GPIO0_EXP1_D5,
+ GPIO0_EXP1_D6,
+ GPIO0_EXP1_D7,
+#endif
+#if defined(GPIO1_EXP1)
+ GPIO1_EXP1_A0 = 192,
+ GPIO1_EXP1_A1,
+ GPIO1_EXP1_A2,
+ GPIO1_EXP1_A3,
+ GPIO1_EXP1_A4,
+ GPIO1_EXP1_A5,
+ GPIO1_EXP1_A6,
+ GPIO1_EXP1_A7,
+ GPIO1_EXP1_B0 = 200,
+ GPIO1_EXP1_B1,
+ GPIO1_EXP1_B2,
+ GPIO1_EXP1_B3,
+ GPIO1_EXP1_B4,
+ GPIO1_EXP1_B5,
+ GPIO1_EXP1_B6,
+ GPIO1_EXP1_B7,
+ GPIO1_EXP1_C0 = 208,
+ GPIO1_EXP1_C1,
+ GPIO1_EXP1_C2,
+ GPIO1_EXP1_C3,
+ GPIO1_EXP1_C4,
+ GPIO1_EXP1_C5,
+ GPIO1_EXP1_C6,
+ GPIO1_EXP1_C7,
+ GPIO1_EXP1_D0 = 216,
+ GPIO1_EXP1_D1,
+ GPIO1_EXP1_D2,
+ GPIO1_EXP1_D3,
+ GPIO1_EXP1_D4,
+ GPIO1_EXP1_D5,
+ GPIO1_EXP1_D6,
+ GPIO1_EXP1_D7,
+#endif
+#if defined(GPIO2_EXP1)
+ GPIO2_EXP1_A0 = 224,
+ GPIO2_EXP1_A1,
+ GPIO2_EXP1_A2,
+ GPIO2_EXP1_A3,
+ GPIO2_EXP1_A4,
+ GPIO2_EXP1_A5,
+ GPIO2_EXP1_A6,
+ GPIO2_EXP1_A7,
+ GPIO2_EXP1_B0 = 232,
+ GPIO2_EXP1_B1,
+ GPIO2_EXP1_B2,
+ GPIO2_EXP1_B3,
+ GPIO2_EXP1_B4,
+ GPIO2_EXP1_B5,
+ GPIO2_EXP1_B6,
+ GPIO2_EXP1_B7,
+ GPIO2_EXP1_C0 = 240,
+ GPIO2_EXP1_C1,
+ GPIO2_EXP1_C2,
+ GPIO2_EXP1_C3,
+ GPIO2_EXP1_C4,
+ GPIO2_EXP1_C5,
+ GPIO2_EXP1_C6,
+ GPIO2_EXP1_C7,
+ GPIO2_EXP1_D0 = 248,
+ GPIO2_EXP1_D1,
+ GPIO2_EXP1_D2,
+ GPIO2_EXP1_D3,
+ GPIO2_EXP1_D4,
+ GPIO2_EXP1_D5,
+ GPIO2_EXP1_D6,
+ GPIO2_EXP1_D7,
+#endif
+#if defined(GPIO3_EXP1)
+ GPIO3_EXP1_A0 = 256,
+ GPIO3_EXP1_A1,
+ GPIO3_EXP1_A2,
+ GPIO3_EXP1_A3,
+ GPIO3_EXP1_A4,
+ GPIO3_EXP1_A5,
+ GPIO3_EXP1_A6,
+ GPIO3_EXP1_A7,
+ GPIO3_EXP1_B0 = 264,
+ GPIO3_EXP1_B1,
+ GPIO3_EXP1_B2,
+ GPIO3_EXP1_B3,
+ GPIO3_EXP1_B4,
+ GPIO3_EXP1_B5,
+ GPIO3_EXP1_B6,
+ GPIO3_EXP1_B7,
+ GPIO3_EXP1_C0 = 272,
+ GPIO3_EXP1_C1,
+ GPIO3_EXP1_C2,
+ GPIO3_EXP1_C3,
+ GPIO3_EXP1_C4,
+ GPIO3_EXP1_C5,
+ GPIO3_EXP1_C6,
+ GPIO3_EXP1_C7,
+ GPIO3_EXP1_D0 = 280,
+ GPIO3_EXP1_D1,
+ GPIO3_EXP1_D2,
+ GPIO3_EXP1_D3,
+ GPIO3_EXP1_D4,
+ GPIO3_EXP1_D5,
+ GPIO3_EXP1_D6,
+ GPIO3_EXP1_D7,
+#endif
+#if defined(GPIO4_EXP1)
+ GPIO4_EXP1_A0 = 288,
+ GPIO4_EXP1_A1,
+ GPIO4_EXP1_A2,
+ GPIO4_EXP1_A3,
+ GPIO4_EXP1_A4,
+ GPIO4_EXP1_A5,
+ GPIO4_EXP1_A6,
+ GPIO4_EXP1_A7,
+ GPIO4_EXP1_B0 = 296,
+ GPIO4_EXP1_B1,
+ GPIO4_EXP1_B2,
+ GPIO4_EXP1_B3,
+ GPIO4_EXP1_B4,
+ GPIO4_EXP1_B5,
+ GPIO4_EXP1_B6,
+ GPIO4_EXP1_B7,
+ GPIO4_EXP1_C0 = 304,
+ GPIO4_EXP1_C1,
+ GPIO4_EXP1_C2,
+ GPIO4_EXP1_C3,
+ GPIO4_EXP1_C4,
+ GPIO4_EXP1_C5,
+ GPIO4_EXP1_C6,
+ GPIO4_EXP1_C7,
+ GPIO4_EXP1_D0 = 312,
+ GPIO4_EXP1_D1,
+ GPIO4_EXP1_D2,
+ GPIO4_EXP1_D3,
+ GPIO4_EXP1_D4,
+ GPIO4_EXP1_D5,
+ GPIO4_EXP1_D6,
+ GPIO4_EXP1_D7,
+#endif
+#if defined(GPIO0_EXP2)
+ GPIO0_EXP2_A0 = 320,
+ GPIO0_EXP2_A1,
+ GPIO0_EXP2_A2,
+ GPIO0_EXP2_A3,
+ GPIO0_EXP2_A4,
+ GPIO0_EXP2_A5,
+ GPIO0_EXP2_A6,
+ GPIO0_EXP2_A7,
+ GPIO0_EXP2_B0 = 328,
+ GPIO0_EXP2_B1,
+ GPIO0_EXP2_B2,
+ GPIO0_EXP2_B3,
+ GPIO0_EXP2_B4,
+ GPIO0_EXP2_B5,
+ GPIO0_EXP2_B6,
+ GPIO0_EXP2_B7,
+ GPIO0_EXP2_C0 = 336,
+ GPIO0_EXP2_C1,
+ GPIO0_EXP2_C2,
+ GPIO0_EXP2_C3,
+ GPIO0_EXP2_C4,
+ GPIO0_EXP2_C5,
+ GPIO0_EXP2_C6,
+ GPIO0_EXP2_C7,
+ GPIO0_EXP2_D0 = 344,
+ GPIO0_EXP2_D1,
+ GPIO0_EXP2_D2,
+ GPIO0_EXP2_D3,
+ GPIO0_EXP2_D4,
+ GPIO0_EXP2_D5,
+ GPIO0_EXP2_D6,
+ GPIO0_EXP2_D7,
+#endif
+#if defined(GPIO1_EXP2)
+ GPIO1_EXP2_A0 = 352,
+ GPIO1_EXP2_A1,
+ GPIO1_EXP2_A2,
+ GPIO1_EXP2_A3,
+ GPIO1_EXP2_A4,
+ GPIO1_EXP2_A5,
+ GPIO1_EXP2_A6,
+ GPIO1_EXP2_A7,
+ GPIO1_EXP2_B0 = 360,
+ GPIO1_EXP2_B1,
+ GPIO1_EXP2_B2,
+ GPIO1_EXP2_B3,
+ GPIO1_EXP2_B4,
+ GPIO1_EXP2_B5,
+ GPIO1_EXP2_B6,
+ GPIO1_EXP2_B7,
+ GPIO1_EXP2_C0 = 368,
+ GPIO1_EXP2_C1,
+ GPIO1_EXP2_C2,
+ GPIO1_EXP2_C3,
+ GPIO1_EXP2_C4,
+ GPIO1_EXP2_C5,
+ GPIO1_EXP2_C6,
+ GPIO1_EXP2_C7,
+ GPIO1_EXP2_D0 = 376,
+ GPIO1_EXP2_D1,
+ GPIO1_EXP2_D2,
+ GPIO1_EXP2_D3,
+ GPIO1_EXP2_D4,
+ GPIO1_EXP2_D5,
+ GPIO1_EXP2_D6,
+ GPIO1_EXP2_D7,
+#endif
+#if defined(GPIO2_EXP2)
+ GPIO2_EXP2_A0 = 384,
+ GPIO2_EXP2_A1,
+ GPIO2_EXP2_A2,
+ GPIO2_EXP2_A3,
+ GPIO2_EXP2_A4,
+ GPIO2_EXP2_A5,
+ GPIO2_EXP2_A6,
+ GPIO2_EXP2_A7,
+ GPIO2_EXP2_B0 = 392,
+ GPIO2_EXP2_B1,
+ GPIO2_EXP2_B2,
+ GPIO2_EXP2_B3,
+ GPIO2_EXP2_B4,
+ GPIO2_EXP2_B5,
+ GPIO2_EXP2_B6,
+ GPIO2_EXP2_B7,
+ GPIO2_EXP2_C0 = 400,
+ GPIO2_EXP2_C1,
+ GPIO2_EXP2_C2,
+ GPIO2_EXP2_C3,
+ GPIO2_EXP2_C4,
+ GPIO2_EXP2_C5,
+ GPIO2_EXP2_C6,
+ GPIO2_EXP2_C7,
+ GPIO2_EXP2_D0 = 408,
+ GPIO2_EXP2_D1,
+ GPIO2_EXP2_D2,
+ GPIO2_EXP2_D3,
+ GPIO2_EXP2_D4,
+ GPIO2_EXP2_D5,
+ GPIO2_EXP2_D6,
+ GPIO2_EXP2_D7,
+#endif
+#if defined(GPIO3_EXP2)
+ GPIO3_EXP2_A0 = 416,
+ GPIO3_EXP2_A1,
+ GPIO3_EXP2_A2,
+ GPIO3_EXP2_A3,
+ GPIO3_EXP2_A4,
+ GPIO3_EXP2_A5,
+ GPIO3_EXP2_A6,
+ GPIO3_EXP2_A7,
+ GPIO3_EXP2_B0 = 424,
+ GPIO3_EXP2_B1,
+ GPIO3_EXP2_B2,
+ GPIO3_EXP2_B3,
+ GPIO3_EXP2_B4,
+ GPIO3_EXP2_B5,
+ GPIO3_EXP2_B6,
+ GPIO3_EXP2_B7,
+ GPIO3_EXP2_C0 = 432,
+ GPIO3_EXP2_C1,
+ GPIO3_EXP2_C2,
+ GPIO3_EXP2_C3,
+ GPIO3_EXP2_C4,
+ GPIO3_EXP2_C5,
+ GPIO3_EXP2_C6,
+ GPIO3_EXP2_C7,
+ GPIO3_EXP2_D0 = 440,
+ GPIO3_EXP2_D1,
+ GPIO3_EXP2_D2,
+ GPIO3_EXP2_D3,
+ GPIO3_EXP2_D4,
+ GPIO3_EXP2_D5,
+ GPIO3_EXP2_D6,
+ GPIO3_EXP2_D7,
+#endif
+#if defined(GPIO4_EXP2)
+ GPIO4_EXP2_A0 = 448,
+ GPIO4_EXP2_A1,
+ GPIO4_EXP2_A2,
+ GPIO4_EXP2_A3,
+ GPIO4_EXP2_A4,
+ GPIO4_EXP2_A5,
+ GPIO4_EXP2_A6,
+ GPIO4_EXP2_A7,
+ GPIO4_EXP2_B0 = 456,
+ GPIO4_EXP2_B1,
+ GPIO4_EXP2_B2,
+ GPIO4_EXP2_B3,
+ GPIO4_EXP2_B4,
+ GPIO4_EXP2_B5,
+ GPIO4_EXP2_B6,
+ GPIO4_EXP2_B7,
+ GPIO4_EXP2_C0 = 464,
+ GPIO4_EXP2_C1,
+ GPIO4_EXP2_C2,
+ GPIO4_EXP2_C3,
+ GPIO4_EXP2_C4,
+ GPIO4_EXP2_C5,
+ GPIO4_EXP2_C6,
+ GPIO4_EXP2_C7,
+ GPIO4_EXP2_D0 = 472,
+ GPIO4_EXP2_D1,
+ GPIO4_EXP2_D2,
+ GPIO4_EXP2_D3,
+ GPIO4_EXP2_D4,
+ GPIO4_EXP2_D5,
+ GPIO4_EXP2_D6,
+ GPIO4_EXP2_D7,
+#endif
+#if defined(GPIO0_EXP3)
+ GPIO0_EXP3_A0 = 480,
+ GPIO0_EXP3_A1,
+ GPIO0_EXP3_A2,
+ GPIO0_EXP3_A3,
+ GPIO0_EXP3_A4,
+ GPIO0_EXP3_A5,
+ GPIO0_EXP3_A6,
+ GPIO0_EXP3_A7,
+ GPIO0_EXP3_B0 = 488,
+ GPIO0_EXP3_B1,
+ GPIO0_EXP3_B2,
+ GPIO0_EXP3_B3,
+ GPIO0_EXP3_B4,
+ GPIO0_EXP3_B5,
+ GPIO0_EXP3_B6,
+ GPIO0_EXP3_B7,
+ GPIO0_EXP3_C0 = 496,
+ GPIO0_EXP3_C1,
+ GPIO0_EXP3_C2,
+ GPIO0_EXP3_C3,
+ GPIO0_EXP3_C4,
+ GPIO0_EXP3_C5,
+ GPIO0_EXP3_C6,
+ GPIO0_EXP3_C7,
+ GPIO0_EXP3_D0 = 504,
+ GPIO0_EXP3_D1,
+ GPIO0_EXP3_D2,
+ GPIO0_EXP3_D3,
+ GPIO0_EXP3_D4,
+ GPIO0_EXP3_D5,
+ GPIO0_EXP3_D6,
+ GPIO0_EXP3_D7,
+#endif
+#if defined(GPIO1_EXP3)
+ GPIO1_EXP3_A0 = 512,
+ GPIO1_EXP3_A1,
+ GPIO1_EXP3_A2,
+ GPIO1_EXP3_A3,
+ GPIO1_EXP3_A4,
+ GPIO1_EXP3_A5,
+ GPIO1_EXP3_A6,
+ GPIO1_EXP3_A7,
+ GPIO1_EXP3_B0 = 520,
+ GPIO1_EXP3_B1,
+ GPIO1_EXP3_B2,
+ GPIO1_EXP3_B3,
+ GPIO1_EXP3_B4,
+ GPIO1_EXP3_B5,
+ GPIO1_EXP3_B6,
+ GPIO1_EXP3_B7,
+ GPIO1_EXP3_C0 = 528,
+ GPIO1_EXP3_C1,
+ GPIO1_EXP3_C2,
+ GPIO1_EXP3_C3,
+ GPIO1_EXP3_C4,
+ GPIO1_EXP3_C5,
+ GPIO1_EXP3_C6,
+ GPIO1_EXP3_C7,
+ GPIO1_EXP3_D0 = 536,
+ GPIO1_EXP3_D1,
+ GPIO1_EXP3_D2,
+ GPIO1_EXP3_D3,
+ GPIO1_EXP3_D4,
+ GPIO1_EXP3_D5,
+ GPIO1_EXP3_D6,
+ GPIO1_EXP3_D7,
+#endif
+#if defined(GPIO2_EXP3)
+ GPIO2_EXP3_A0 = 544,
+ GPIO2_EXP3_A1,
+ GPIO2_EXP3_A2,
+ GPIO2_EXP3_A3,
+ GPIO2_EXP3_A4,
+ GPIO2_EXP3_A5,
+ GPIO2_EXP3_A6,
+ GPIO2_EXP3_A7,
+ GPIO2_EXP3_B0 = 552,
+ GPIO2_EXP3_B1,
+ GPIO2_EXP3_B2,
+ GPIO2_EXP3_B3,
+ GPIO2_EXP3_B4,
+ GPIO2_EXP3_B5,
+ GPIO2_EXP3_B6,
+ GPIO2_EXP3_B7,
+ GPIO2_EXP3_C0 = 560,
+ GPIO2_EXP3_C1,
+ GPIO2_EXP3_C2,
+ GPIO2_EXP3_C3,
+ GPIO2_EXP3_C4,
+ GPIO2_EXP3_C5,
+ GPIO2_EXP3_C6,
+ GPIO2_EXP3_C7,
+ GPIO2_EXP3_D0 = 568,
+ GPIO2_EXP3_D1,
+ GPIO2_EXP3_D2,
+ GPIO2_EXP3_D3,
+ GPIO2_EXP3_D4,
+ GPIO2_EXP3_D5,
+ GPIO2_EXP3_D6,
+ GPIO2_EXP3_D7,
+#endif
+#if defined(GPIO3_EXP3)
+ GPIO3_EXP3_A0 = 576,
+ GPIO3_EXP3_A1,
+ GPIO3_EXP3_A2,
+ GPIO3_EXP3_A3,
+ GPIO3_EXP3_A4,
+ GPIO3_EXP3_A5,
+ GPIO3_EXP3_A6,
+ GPIO3_EXP3_A7,
+ GPIO3_EXP3_B0 = 584,
+ GPIO3_EXP3_B1,
+ GPIO3_EXP3_B2,
+ GPIO3_EXP3_B3,
+ GPIO3_EXP3_B4,
+ GPIO3_EXP3_B5,
+ GPIO3_EXP3_B6,
+ GPIO3_EXP3_B7,
+ GPIO3_EXP3_C0 = 592,
+ GPIO3_EXP3_C1,
+ GPIO3_EXP3_C2,
+ GPIO3_EXP3_C3,
+ GPIO3_EXP3_C4,
+ GPIO3_EXP3_C5,
+ GPIO3_EXP3_C6,
+ GPIO3_EXP3_C7,
+ GPIO3_EXP3_D0 = 600,
+ GPIO3_EXP3_D1,
+ GPIO3_EXP3_D2,
+ GPIO3_EXP3_D3,
+ GPIO3_EXP3_D4,
+ GPIO3_EXP3_D5,
+ GPIO3_EXP3_D6,
+ GPIO3_EXP3_D7,
+#endif
+#if defined(GPIO4_EXP3)
+ GPIO4_EXP3_A0 = 608,
+ GPIO4_EXP3_A1,
+ GPIO4_EXP3_A2,
+ GPIO4_EXP3_A3,
+ GPIO4_EXP3_A4,
+ GPIO4_EXP3_A5,
+ GPIO4_EXP3_A6,
+ GPIO4_EXP3_A7,
+ GPIO4_EXP3_B0 = 616,
+ GPIO4_EXP3_B1,
+ GPIO4_EXP3_B2,
+ GPIO4_EXP3_B3,
+ GPIO4_EXP3_B4,
+ GPIO4_EXP3_B5,
+ GPIO4_EXP3_B6,
+ GPIO4_EXP3_B7,
+ GPIO4_EXP3_C0 = 624,
+ GPIO4_EXP3_C1,
+ GPIO4_EXP3_C2,
+ GPIO4_EXP3_C3,
+ GPIO4_EXP3_C4,
+ GPIO4_EXP3_C5,
+ GPIO4_EXP3_C6,
+ GPIO4_EXP3_C7,
+ GPIO4_EXP3_D0 = 632,
+ GPIO4_EXP3_D1,
+ GPIO4_EXP3_D2,
+ GPIO4_EXP3_D3,
+ GPIO4_EXP3_D4,
+ GPIO4_EXP3_D5,
+ GPIO4_EXP3_D6,
+ GPIO4_EXP3_D7,
#endif
GPIO_NUM_MAX
} ePINCTRL_PIN;
@@ -476,7 +986,7 @@ typedef enum {
PIN_CONFIG_PUL_UP = PIN_CONFIG_PUL_DEFAULT,
PIN_CONFIG_PUL_DOWN = PIN_CONFIG_PUL_DEFAULT,
PIN_CONFIG_PUL_KEEP = PIN_CONFIG_PUL_DEFAULT,
-#elif defined(SOC_RK3588)
+#elif defined(SOC_RK3588) || defined(SOC_RK3576)
PIN_CONFIG_PUL_NORMAL = (0x0 << SHIFT_PUL | FLAG_PUL),
PIN_CONFIG_PUL_DOWN = (0x1 << SHIFT_PUL | FLAG_PUL),
PIN_CONFIG_PUL_KEEP = (0x2 << SHIFT_PUL | FLAG_PUL),
@@ -490,7 +1000,7 @@ typedef enum {
PIN_CONFIG_PUL_DEFAULT = PIN_CONFIG_PUL_NORMAL,
#endif
-#if defined(SOC_RK3568) || defined(SOC_RV1106) || defined(SOC_RK3562)
+#if defined(SOC_RK3568) || defined(SOC_RV1106) || defined(SOC_RK3562) || defined(RKMCU_RK2118)
PIN_CONFIG_DRV_LEVEL0 = (0x1 << SHIFT_DRV | FLAG_DRV),
PIN_CONFIG_DRV_LEVEL1 = (0x3 << SHIFT_DRV | FLAG_DRV),
PIN_CONFIG_DRV_LEVEL2 = (0x7 << SHIFT_DRV | FLAG_DRV),
@@ -504,6 +1014,14 @@ typedef enum {
PIN_CONFIG_DRV_LEVEL2 = (0x1 << SHIFT_DRV | FLAG_DRV),
PIN_CONFIG_DRV_LEVEL3 = (0x3 << SHIFT_DRV | FLAG_DRV),
PIN_CONFIG_DRV_LEVEL_DEFAULT = PIN_CONFIG_DRV_LEVEL2,
+#elif defined(SOC_RK3576)
+ PIN_CONFIG_DRV_LEVEL0 = (0x0 << SHIFT_DRV | FLAG_DRV),
+ PIN_CONFIG_DRV_LEVEL1 = (0x4 << SHIFT_DRV | FLAG_DRV),
+ PIN_CONFIG_DRV_LEVEL2 = (0x2 << SHIFT_DRV | FLAG_DRV),
+ PIN_CONFIG_DRV_LEVEL3 = (0x6 << SHIFT_DRV | FLAG_DRV),
+ PIN_CONFIG_DRV_LEVEL4 = (0x1 << SHIFT_DRV | FLAG_DRV),
+ PIN_CONFIG_DRV_LEVEL5 = (0x5 << SHIFT_DRV | FLAG_DRV),
+ PIN_CONFIG_DRV_LEVEL_DEFAULT = PIN_CONFIG_DRV_LEVEL2,
#else
PIN_CONFIG_DRV_LEVEL0 = (0x0 << SHIFT_DRV | FLAG_DRV),
PIN_CONFIG_DRV_LEVEL1 = (0x1 << SHIFT_DRV | FLAG_DRV),
@@ -678,6 +1196,9 @@ HAL_Status HAL_PINCTRL_DeInit(void);
HAL_Status HAL_PINCTRL_SetParam(eGPIO_bankId bank, uint32_t mPins, ePINCTRL_configParam param);
HAL_Status HAL_PINCTRL_SetIOMUX(eGPIO_bankId bank, uint32_t mPins, ePINCTRL_configParam param);
+#ifdef RM0_IO
+HAL_Status HAL_PINCTRL_SetRMIO(eGPIO_bankId bank, uint32_t rmioPin, eRMIO_Name rmioFunc);
+#endif
HAL_Status HAL_PINCTRL_IOFuncSelForCIF(eIOFUNC_SEL mode);
HAL_Status HAL_PINCTRL_IOFuncSelForEMMC(eIOFUNC_SEL mode);
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/soc.h b/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/soc.h
index 7c0334510..8318bd75c 100644
--- a/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/soc.h
+++ b/Ubiquitous/XiZi_AIoT/services/drivers/3568/include/soc.h
@@ -415,6 +415,7 @@ typedef enum CLOCK_Name {
ACLK_USB = CLK(ACLK_USB_SEL, 0U),
HCLK_USB = CLK(HCLK_USB_SEL, 0U),
PCLK_USB = CLK(0U, PCLK_USB_DIV),
+ CLK_SDMMC0 = CLK(CLK_SDMMC0_SEL, 0U),
} eCLOCK_Name;
#endif
/****************************************MBOX********************************************/
@@ -425,10 +426,10 @@ typedef enum CLOCK_Name {
#define GRF_DS_BIT_PER_PIN (8)
#define GRF_PULL_BIT_PER_PIN (2)
/****************************************GPIO********************************************/
-#ifdef GPIO_VER_ID
-#undef GPIO_VER_ID
-#define GPIO_VER_ID (0x01000C2BU)
-#endif
+// #ifdef GPIO_VER_ID
+// #undef GPIO_VER_ID
+// #define GPIO_VER_ID (0x01000C2BU)
+// #endif
/****************************************PMU*********************************************/
#ifndef __ASSEMBLY__
typedef enum PD_Id {
@@ -438,6 +439,10 @@ typedef enum PD_Id {
/****************************************FSPI********************************************/
#define FSPI_CHIP_CNT (2)
+/****************************************WDT*********************************************/
+#define GLB_RST_SND_WDT GLB_RST_SND_WDT0
+#define GLB_RST_FST_WDT GLB_RST_FST_WDT0
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/clock/epit.c b/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/clock/epit.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/board_network.c b/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/board_network.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet.h b/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet_drv.c b/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet_drv.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet_private.h b/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet_private.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet_test.c b/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/enet/enet_test.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/include/soc_memory_map.h b/Ubiquitous/XiZi_AIoT/services/drivers/imx6q-sabrelite/include/soc_memory_map.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs.c b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs.c
index d4c2243e2..a9d5aaa96 100644
--- a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs.c
+++ b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs.c
@@ -63,7 +63,7 @@ static struct FileDescriptor fd_table[MAX_SUPPORT_FD];
struct MemFsRange MemFsRange;
/// @brief Using syscall to get fs.img real location in the memory
-void MemFsInit(uintptr_t _binary_fs_img_start, uint32_t fs_img_len)
+void MemFsInit(uintptr_t _binary_fs_img_start, uintptr_t fs_img_len)
{
MemFsRange.memfs_start = _binary_fs_img_start;
MemFsRange.memfs_nr_blocks = fs_img_len / BLOCK_SIZE;
@@ -251,12 +251,12 @@ struct Inode* InodeParentSeek(struct Inode* source, char* path, char* name)
/// @brief Alloc a new Inode using type
static struct Inode* InodeAlloc(int type)
{
- int inum;
+ int inum = 0;
struct Inode* inode;
struct SuperBlock sb;
ReadSuperBlock(&sb);
- for (inum = 1; inum < sb.ninodes; inum++) {
+ for (inum = 1; inum < (int)sb.ninodes; inum++) {
uint8_t* block = BlockRead(BLOCK_INDEX(inum));
inode = (struct Inode*)block + INODE_INDEX(inum);
if (inode->type == 0) {
diff --git a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c
index 3bfc42b89..c7a8fb99d 100644
--- a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c
+++ b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c
@@ -352,10 +352,10 @@ int main(int argc, char* argv[])
sys_state_info info;
get_memblock_info(&info);
- int len = info.memblock_info.memblock_end - info.memblock_info.memblock_start;
+ uintptr_t len = info.memblock_info.memblock_end - info.memblock_info.memblock_start;
mmap(FS_IMG_ADDR, info.memblock_info.memblock_start, len, false);
- MemFsInit((uintptr_t)FS_IMG_ADDR, (uint32_t)len);
+ MemFsInit((uintptr_t)FS_IMG_ADDR, (uintptr_t)len);
if (register_server("MemFS") < 0) {
printf("register server name: %s failed.\n", "MemFs");
diff --git a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/include/fs.h b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/include/fs.h
index 17a536ece..a26a1a758 100644
--- a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/include/fs.h
+++ b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/include/fs.h
@@ -61,7 +61,7 @@ Modification:
// memory fs range
struct MemFsRange {
uintptr_t memfs_start;
- uint32_t memfs_nr_blocks;
+ uintptr_t memfs_nr_blocks;
};
// memfs file type
@@ -89,9 +89,9 @@ struct Inode {
};
// directory entry
-#define DIR_NAME_SIZE 30
+#define DIR_NAME_SIZE 28
struct DirectEntry {
- uint16_t inum;
+ uint32_t inum;
char name[DIR_NAME_SIZE];
};
@@ -105,7 +105,7 @@ struct FileDescriptor {
// range of memory fs
extern struct MemFsRange MemFsRange;
-void MemFsInit(uintptr_t _binary_fs_img_start, uint32_t fs_img_len);
+void MemFsInit(uintptr_t _binary_fs_img_start, uintptr_t fs_img_len);
void ReadSuperBlock(struct SuperBlock*);
// fs Inode ops
diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c
index 0ff25461f..27fe4d687 100644
--- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c
+++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c
@@ -131,14 +131,14 @@ bool ipc_msg_get_nth_arg(struct IpcMsg* msg, const int arg_num, void* data, cons
return true;
}
-void ipc_msg_send_wait(struct IpcMsg* msg)
+void ipc_msg_send_wait(struct Session* session, struct IpcMsg* msg)
{
msg->header.magic = IPC_MSG_MAGIC;
msg->header.valid = 1;
msg->header.done = 0;
while (msg->header.done == 0) {
/// @todo syscall yield with prio decrease
- yield(SYS_TASK_YIELD_BLOCK_IPC);
+ wait_session_call(session);
}
assert(msg->header.done == 1);
}
@@ -155,7 +155,7 @@ int ipc_session_wait(struct Session* session)
struct IpcMsg* msg = IPCSESSION_MSG(session);
while (msg->header.done == 0) {
/// @todo syscall yield with prio decrease
- yield(SYS_TASK_YIELD_BLOCK_IPC);
+ wait_session_call(session);
}
assert(msg->header.done == 1);
return msg->header.ret_val;
diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.h b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.h
index 82af08799..bdfb4e1f0 100644
--- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.h
+++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.h
@@ -180,7 +180,7 @@ __attribute__((__always_inline__)) static inline bool ipc_session_forward(struct
struct IpcMsg* new_ipc_msg(struct Session* session, const int argc, const int* arg_size);
bool ipc_msg_set_nth_arg(struct IpcMsg* msg, const int arg_num, const void* const data, const int len);
bool ipc_msg_get_nth_arg(struct IpcMsg* msg, const int arg_num, void* data, const int len);
-void ipc_msg_send_wait(struct IpcMsg* msg);
+void ipc_msg_send_wait(struct Session* session, struct IpcMsg* msg);
void ipc_msg_send_nowait(struct IpcMsg* msg);
int ipc_session_wait(struct Session* session);
@@ -230,7 +230,7 @@ void ipc_server_loop(struct IpcNode* ipc_node);
struct IpcMsg* msg = IPC_CREATE_MSG_FUNC(ipc_name)(session, _VA_FRONT_ARG##argc(__VA_ARGS__)); \
int ret = IPC_MSG_ARGS_COPY_SET_FUNC(ipc_name)(msg, _VA_FRONT_ARG##argc(__VA_ARGS__)); \
ret = ipc_msg_set_opcode(msg, ipc_name); \
- ipc_msg_send_wait(msg); \
+ ipc_msg_send_wait(session, msg); \
ret = IPC_MSG_ARGS_COPY_GET_FUNC(ipc_name)(msg, _VA_FRONT_ARG##argc(__VA_ARGS__)); \
int32_t res = 0; \
ipc_msg_get_return(msg, &res); \
@@ -278,9 +278,10 @@ uintptr_t _ipc_buf_to_addr(char* buf);
char addr_buf[17]; \
_ipc_addr_to_buf((uintptr_t)msg, addr_buf); \
char* param[] = { #ipc_name, addr_buf, NULL }; \
+ msg->header.handling = 1; \
int tid = thread(IPC_THREAD_SERVE(ipc_name), #ipc_name, param); \
- if (tid > 0) { \
- msg->header.handling = 1; \
+ if (tid <= 0) { \
+ msg->header.handling = 0; \
} \
return 0; \
}
diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h b/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h
index 196c6bf5b..0d655650e 100644
--- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h
+++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h
@@ -36,7 +36,7 @@ Modification:
#include "libserial.h"
struct Session {
- int id;
+ uintptr_t id;
int capacity;
int head;
int tail;
diff --git a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c
index 8bdf03709..3b4d215f2 100644
--- a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c
+++ b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c
@@ -12,6 +12,11 @@
#include "usyscall.h"
#include "libmem.h"
+uintptr_t sys_test()
+{
+ return syscall(SYSCALL_TEST, 0, 0, 0, 0);
+}
+
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv)
{
/* read elf image */
@@ -72,6 +77,11 @@ int close_session(struct Session* session)
return syscall(SYSCALL_CLOSE_SESSION, (intptr_t)session, 0, 0, 0);
}
+int wait_session_call(struct Session* userland_session)
+{
+ return syscall(SYSCALL_WAIT_SESSION, (intptr_t)userland_session, 0, 0, 0);
+}
+
int get_memblock_info(sys_state_info* info)
{
return syscall(SYSCALL_SYS_STATE, SYS_STATE_MEMBLOCK_INFO, (intptr_t)info, 0, 0);
@@ -102,6 +112,11 @@ int show_cpu()
return syscall(SYSCALL_SYS_STATE, SYS_STATE_SHOW_CPU_INFO, 0, 0, 0);
}
+int show_actree()
+{
+ return syscall(SYSCALL_SYS_STATE, SYS_STATE_SHOW_ACTREE, 0, 0, 0);
+}
+
uintptr_t get_second()
{
sys_state_info info;
@@ -118,8 +133,12 @@ uintptr_t get_tick()
uintptr_t mmap(uintptr_t vaddr, uintptr_t paddr, int len, bool is_dev)
{
+ sys_mmap_info info = {
+ .type = SYS_MMAP_NORMAL,
+ .is_dev = is_dev,
+ };
uintptr_t vaddr_inner = vaddr, paddr_inner = paddr;
- if (syscall(SYSCALL_MMAP, (intptr_t)&vaddr_inner, (intptr_t)&paddr_inner, (intptr_t)len, (intptr_t)is_dev) < 0) {
+ if (syscall(SYSCALL_MMAP, (intptr_t)&vaddr_inner, (intptr_t)&paddr_inner, (intptr_t)len, (intptr_t)&info) < 0) {
return (uintptr_t)NULL;
}
return vaddr_inner;
@@ -127,7 +146,20 @@ uintptr_t mmap(uintptr_t vaddr, uintptr_t paddr, int len, bool is_dev)
int naive_mmap(uintptr_t* vaddr, uintptr_t* paddr, int len, bool is_dev)
{
- return syscall(SYSCALL_MMAP, (uintptr_t)vaddr, (intptr_t)paddr, (intptr_t)len, (intptr_t)is_dev);
+ sys_mmap_info info = {
+ .type = SYS_MMAP_NORMAL,
+ .is_dev = is_dev,
+ };
+ return syscall(SYSCALL_MMAP, (uintptr_t)vaddr, (intptr_t)paddr, (intptr_t)len, (intptr_t)&info);
+}
+
+int mmap_with_attr(uintptr_t vaddr, uintptr_t paddr, int len, uintptr_t attr)
+{
+ sys_mmap_info info = {
+ .type = SYS_MMAP_CUSTOMIZE,
+ .attr = attr,
+ };
+ return syscall(SYSCALL_MMAP, (intptr_t)vaddr, (intptr_t)paddr, (intptr_t)len, (intptr_t)&info);
}
int register_irq(int irq, int opcode)
@@ -153,4 +185,9 @@ bool semaphore_wait(int sem_id)
bool semaphore_signal(int sem_id)
{
return syscall(SYSCALL_SEMAPHORE, (intptr_t)SYS_SEM_SIGNAL, (intptr_t)sem_id, 0, 0);
+}
+
+int sleep(intptr_t ms)
+{
+ return syscall(SYSCALL_SLEEP, (intptr_t)ms, 0, 0, 0);
}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h
index e76f684a1..79cc81ed3 100644
--- a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h
+++ b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h
@@ -34,6 +34,9 @@
#define SYSCALL_KILL 12 // kill the task by id
#define SYSCALL_SEMAPHORE 13 // semaphore related operations
+#define SYSCALL_SLEEP 14 // sleep
+
+#define SYSCALL_WAIT_SESSION 15
// clang-format on
typedef enum {
@@ -46,6 +49,7 @@ typedef enum {
SYS_STATE_SHOW_CPU_INFO,
SYS_STATE_GET_CURRENT_TICK,
SYS_STATE_GET_CURRENT_SECOND,
+ SYS_STATE_SHOW_ACTREE,
} sys_state_option;
typedef enum {
@@ -54,6 +58,17 @@ typedef enum {
SYS_TASK_YIELD_BLOCK_IPC = 0x2,
} task_yield_reason;
+typedef enum {
+ SYS_MMAP_NORMAL = 0x0,
+ SYS_MMAP_CUSTOMIZE,
+} sys_mmap_type;
+
+typedef struct sys_mmap_info {
+ sys_mmap_type type;
+ uintptr_t attr;
+ bool is_dev;
+} sys_mmap_info;
+
typedef union {
struct {
uintptr_t memblock_start;
@@ -76,6 +91,9 @@ typedef int (*ipc_fsize_fn)(struct Session* session, int fd);
typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len);
int syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4);
+uintptr_t syscall_ori(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4);
+
+uintptr_t sys_test();
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv);
int thread(void* entry, const char* name, char** argv);
@@ -85,12 +103,14 @@ int kill(int pid);
int register_server(char* name);
int session(char* path, int capacity, struct Session* user_session);
-int poll_session(struct Session* userland_session_arr, int arr_capacity);
+int poll_session(struct Session* userland_session, int arr_capacity);
+int wait_session_call(struct Session* userland_session);
int close_session(struct Session* session);
int register_irq(int irq, int opcode);
uintptr_t mmap(uintptr_t vaddr, uintptr_t paddr, int len, bool is_dev);
int naive_mmap(uintptr_t* vaddr, uintptr_t* paddr, int len, bool is_dev);
+int customized_mmap(uintptr_t vaddr, uintptr_t paddr, int len, uintptr_t attr);
int task_heap_base();
int get_memblock_info(sys_state_info* info);
@@ -98,6 +118,7 @@ int set_priority(sys_state_info* info);
int show_task();
int show_mem();
int show_cpu();
+int show_actree();
uintptr_t get_second();
uintptr_t get_tick();
@@ -105,4 +126,6 @@ uintptr_t get_tick();
int semaphore_new(int val);
bool semaphore_free(int sem_id);
bool semaphore_wait(int sem_id);
-bool semaphore_signal(int sem_id);
\ No newline at end of file
+bool semaphore_signal(int sem_id);
+
+int sleep(intptr_t ms);
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/services/semaphore/semaphore_server.c b/Ubiquitous/XiZi_AIoT/services/semaphore/semaphore_server.c
index a835ff8e9..ad4d9978b 100644
--- a/Ubiquitous/XiZi_AIoT/services/semaphore/semaphore_server.c
+++ b/Ubiquitous/XiZi_AIoT/services/semaphore/semaphore_server.c
@@ -41,15 +41,28 @@ int IPC_DO_SERVE_FUNC(Ipc_sem_create)(sem_t* sem, int* count)
return SEMAPHORE_SUC;
}
+
+#define CHECK_SEM_RANGE(sem) \
+ do { \
+ if (*sem < 0 || *sem >= MAX_SUPPORT_SEMAPHORES) { \
+ return SEMAPHORE_ERR; \
+ } \
+ } while (0)
+
+
+#define CHECK_SEM_RANGE_AND_VALID(sem) \
+ do { \
+ CHECK_SEM_RANGE(sem); \
+ \
+ if (!sem_pool[*sem].valid) { \
+ return SEMAPHORE_ERR; \
+ } \
+ } while (0)
+
+
int IPC_DO_SERVE_FUNC(Ipc_sem_delete)(sem_t* sem)
{
- if (*sem < 0 || *sem > MAX_SUPPORT_SEMAPHORES) {
- return SEMAPHORE_ERR;
- }
-
- if (!sem_pool[*sem].valid) {
- return SEMAPHORE_ERR;
- }
+ CHECK_SEM_RANGE_AND_VALID(sem);
sem_pool[*sem].valid = false;
return SEMAPHORE_SUC;
@@ -57,9 +70,7 @@ int IPC_DO_SERVE_FUNC(Ipc_sem_delete)(sem_t* sem)
int IPC_DO_SERVE_FUNC(Ipc_sem_wait)(sem_t* sem, int* timeout)
{
- if (*sem < 0 || *sem > MAX_SUPPORT_SEMAPHORES) {
- return SEMAPHORE_ERR;
- }
+ CHECK_SEM_RANGE(sem);
/// @todo support timeout
// return if sem is freed(no valid) or sem count is sufficient
@@ -72,13 +83,7 @@ int IPC_DO_SERVE_FUNC(Ipc_sem_wait)(sem_t* sem, int* timeout)
int IPC_DO_SERVE_FUNC(Ipc_sem_signal)(sem_t* sem)
{
- if (*sem < 0 || *sem >= MAX_SUPPORT_SEMAPHORES) {
- return SEMAPHORE_ERR;
- }
-
- if (!sem_pool[*sem].valid) {
- return SEMAPHORE_ERR;
- }
+ CHECK_SEM_RANGE_AND_VALID(sem);
sem_pool[*sem].count++;
return SEMAPHORE_SUC;
diff --git a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c
index 34b99616e..dc34c4b73 100644
--- a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c
+++ b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c
@@ -1797,6 +1797,11 @@ void shellShowCpusInfo()
show_cpu();
}
+void shellShowActree()
+{
+ show_actree();
+}
+
#if SHELL_EXEC_UNDEF_FUNC == 1
/**
* @brief shell执行未定义函数
diff --git a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell_cmd_list.c b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell_cmd_list.c
index 762abed40..848555729 100644
--- a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell_cmd_list.c
+++ b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell_cmd_list.c
@@ -40,6 +40,7 @@ extern void shellKill(int pid);
extern void shellShowTasks();
extern void shellShowMemInfo();
extern void shellShowCpusInfo();
+extern void shellShowActree();
#if SHELL_EXEC_UNDEF_FUNC == 1
extern int shellExecute(int argc, char* argv[]);
@@ -118,6 +119,8 @@ const ShellCommand shellCommandList[] = {
showMemInfo, shellShowMemInfo, display memory info),
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
showCpusInfo, shellShowCpusInfo, display cpus info),
+ SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
+ showActree, shellShowActree, display actracer tree),
#if SHELL_EXEC_UNDEF_FUNC == 1
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_DISABLE_RETURN,
diff --git a/Ubiquitous/XiZi_AIoT/services/tools/hosttools/xsconfig.sh b/Ubiquitous/XiZi_AIoT/services/tools/hosttools/xsconfig.sh
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/tools/mkfs/.gitignore b/Ubiquitous/XiZi_AIoT/services/tools/mkfs/.gitignore
new file mode 100644
index 000000000..3337b041d
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/services/tools/mkfs/.gitignore
@@ -0,0 +1 @@
+mkfs
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/services/tools/mkfs/Makefile b/Ubiquitous/XiZi_AIoT/services/tools/mkfs/Makefile
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/tools/mkfs/mkfs.c b/Ubiquitous/XiZi_AIoT/services/tools/mkfs/mkfs.c
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/services/tools/mkfs/mkfs.h b/Ubiquitous/XiZi_AIoT/services/tools/mkfs/mkfs.h
old mode 100755
new mode 100644
index e44e96798..e58a1873c
--- a/Ubiquitous/XiZi_AIoT/services/tools/mkfs/mkfs.h
+++ b/Ubiquitous/XiZi_AIoT/services/tools/mkfs/mkfs.h
@@ -83,8 +83,8 @@ struct Inode {
};
// Directory is a file containing a sequence of DirEntry structures.
-#define DIR_NAME_SIZE 30
+#define DIR_NAME_SIZE 28
struct DirEntry {
- ushort inum;
+ __uint32_t inum;
char name[DIR_NAME_SIZE];
};
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/Makefile
index 1464fe7b9..ba0bc8da0 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/Makefile
+++ b/Ubiquitous/XiZi_AIoT/softkernel/Makefile
@@ -1,4 +1,4 @@
-SRC_DIR := init memory trap task syscall
+SRC_DIR := init memory trap task syscall tools
SRC_FILES := main.c load_apps.S
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/assert.h b/Ubiquitous/XiZi_AIoT/softkernel/include/assert.h
index 8d9d012be..81733ae11 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/assert.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/assert.h
@@ -41,3 +41,5 @@ extern void panic(char*);
#define LIKELY(exp) __builtin_expect(exp, 1)
#define UNLIKELY(exp) __builtin_expect(exp, 0)
+
+#define ERROR_FREE
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/bitmap64.h b/Ubiquitous/XiZi_AIoT/softkernel/include/bitmap64.h
index 77f45e1da..8dbe85790 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/bitmap64.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/bitmap64.h
@@ -46,22 +46,23 @@ static inline void bitmap64_init(struct bitmap64* bitmap)
static inline int bitmap64_alloc(struct bitmap64* bitmap)
{
int free_bit = -1;
- // free bit is the first 0 bit, from [1, 64]
+ // free bit is the first 0 bit, from [0, 63]
free_bit = __builtin_ffsl(~(uint64_t)(bitmap->map));
// handle if bitmap is full (no using 64th bit here)
if (free_bit == 0) {
return -1;
}
- assert(free_bit < 64 && free_bit >= 1);
+ free_bit -= 1;
+ assert(free_bit < 64 && free_bit >= 0);
// alloc and return
- bitmap->map |= (1 << (free_bit - 1));
- return free_bit - 1;
+ bitmap->map |= (1ULL << free_bit);
+ return free_bit;
}
static inline void bitmap64_free(struct bitmap64* bitmap, int idx)
{
// usages of bitmap64 must be correct
- assert((bitmap->map & (1 << idx)) != 0);
+ assert((bitmap->map & (1ULL << idx)) != 0);
// free bit
- bitmap->map &= ~(uint64_t)(1 << idx);
+ bitmap->map &= ~(uint64_t)(1ULL << idx);
}
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h b/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h
index f29533e7c..6c40ba152 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h
@@ -31,12 +31,11 @@ Modification:
#include "list.h"
#include "memlayout.h"
-#include "spinlock.h"
#include
#include
-#define MAX_BUDDY_ORDER (15)
+#define MAX_BUDDY_ORDER (18)
#define FREE_LIST_INDEX(order) \
(1 << order)
@@ -70,7 +69,6 @@ struct KFreeList {
struct KBuddy {
uintptr_t n_pages;
uintptr_t use_lock;
- struct spinlock lock;
struct KFreeList free_list[MAX_BUDDY_ORDER];
struct KPage* first_page;
uintptr_t mem_start;
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/execelf.h b/Ubiquitous/XiZi_AIoT/softkernel/include/execelf.h
old mode 100755
new mode 100644
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/ipc.h b/Ubiquitous/XiZi_AIoT/softkernel/include/ipc.h
index 4bed46666..9100205a4 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/ipc.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/ipc.h
@@ -54,13 +54,20 @@ typedef struct {
struct IpcArgInfo {
uint16_t offset;
uint16_t len;
-};
+ union {
+ uint16_t attr;
+ struct {
+ uint16_t null_ptr : 1;
+ uint16_t reserved : 15;
+ };
+ };
+} __attribute__((packed));
/* [header, ipc_arg_buffer_len[], ipc_arg_buffer[]] */
struct IpcMsg {
ipc_msg_header header;
uintptr_t buf[];
-};
+} __attribute__((packed));
enum {
IPC_ARG_INFO_BASE_OFFSET = sizeof(ipc_msg_header),
};
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/kalloc.h b/Ubiquitous/XiZi_AIoT/softkernel/include/kalloc.h
index 66ec4cddd..8b8d70771 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/kalloc.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/kalloc.h
@@ -29,15 +29,26 @@ Modification:
*************************************************/
#pragma once
-#include "pagetable.h"
+#include "actracer.h"
+#include "rbtree.h"
+
+struct MemUsage {
+ TraceTag tag;
+ RbtTree mem_block_map;
+};
bool module_phymem_init();
char* kalloc(size_t size);
bool kfree(char* vaddr);
bool raw_kfree(char* paddr);
+void* kalloc_by_ownership(TraceTag owner, uintptr_t size);
+bool kfree_by_ownership(TraceTag owner, void* vaddr);
+
char* raw_alloc(size_t size);
bool raw_free(char* paddr);
+void* raw_alloc_by_ownership(TraceTag owner, uintptr_t size);
+bool raw_free_by_ownership(TraceTag owner, void* vaddr);
void show_phymem_info();
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/ksemaphore.h b/Ubiquitous/XiZi_AIoT/softkernel/include/ksemaphore.h
index 99efd6523..2e2c65dbb 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/ksemaphore.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/ksemaphore.h
@@ -23,6 +23,14 @@
#include "list.h"
#include "object_allocator.h"
+#include "rbtree.h"
+
+typedef uintptr_t sem_id_t;
+typedef int32_t sem_val_t;
+
+enum {
+ INVALID_SEM_ID = 0,
+};
/// @warning this is no in use
enum {
@@ -30,22 +38,27 @@ enum {
};
struct ksemaphore {
- uint32_t id;
- int val;
+ sem_id_t id;
+ sem_val_t val;
/* list of waiting threads */
- struct double_list_node wait_list_guard;
+ RbtTree wait_thd_tree;
/* list to manage semaphores */
/// @todo Use RB-Tree to manage all semaphores
struct double_list_node sem_list_node;
};
struct XiziSemaphorePool {
- uint32_t next_sem_id;
+ sem_id_t next_sem_id;
struct slab_allocator allocator;
struct double_list_node sem_list_guard;
+ RbtTree sem_pool_map;
+ sem_val_t nr_sem;
};
void semaphore_pool_init(struct XiziSemaphorePool* sem_pool);
-int ksemaphore_alloc(struct XiziSemaphorePool* sem_pool, int val);
-bool ksemaphore_free(struct XiziSemaphorePool* sem_pool, uint32_t sem_id);
-bool ksemaphore_signal(struct XiziSemaphorePool* sem_pool, uint32_t sem_id);
+sem_id_t ksemaphore_alloc(struct XiziSemaphorePool* sem_pool, sem_val_t val);
+bool ksemaphore_free(struct XiziSemaphorePool* sem_pool, sem_id_t sem_id);
+bool ksemaphore_signal(struct XiziSemaphorePool* sem_pool, sem_id_t sem_id);
+bool ksemaphore_signal_no_wake(struct XiziSemaphorePool* sem_pool, sem_id_t sem_id);
+
+bool ksemaphore_consume(struct XiziSemaphorePool* sem_pool, sem_id_t sem_id, sem_val_t decre);
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/log.h b/Ubiquitous/XiZi_AIoT/softkernel/include/log.h
index a56c0e84c..cdf8812e1 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/log.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/log.h
@@ -35,6 +35,8 @@ Modification:
#define OUTPUT_LEVLE_DEBUG 1
#define OUTPUT_LEVLE_ERROR 2
+#define OUTPUT_LEVLE_TEST 3
+
#define OUTPUT_LEVLE OUTPUT_LEVLE_DEBUG
// #define OUTPUT_LEVLE OUTPUT_LEVLE_LOG
@@ -56,10 +58,21 @@ Modification:
#define DEBUG_PRINTF(f, args...)
#endif
-#define DEBUG(f, args...) \
+#if (OUTPUT_LEVLE >= OUTPUT_LEVLE_TEST)
+#define RECORD_PRINTF(f, args...) \
+ KPrintf(f, ##args)
+#else
+#define RECORD_PRINTF(f, args...)
+#endif
+
+#define DEBUG(f, args...) \
DEBUG_PRINTF("DEBUG: [%s] ", __func__); \
DEBUG_PRINTF(f, ##args)
+#define RECORD(f, args...) \
+ RECORD_PRINTF("DEBUG: [%s] ", __func__); \
+ RECORD_PRINTF(f, ##args)
+
#define ERROR(f, args...) \
KPrintf("ERROR: [%s %d] ", __func__, __LINE__); \
KPrintf(f, ##args)
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/memspace.h b/Ubiquitous/XiZi_AIoT/softkernel/include/memspace.h
index 9c63a20c4..7514c43ae 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/memspace.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/memspace.h
@@ -32,6 +32,7 @@ Modification:
#include "actracer.h"
#include "bitmap64.h"
#include "buddy.h"
+#include "kalloc.h"
#include "list.h"
struct TopLevelPageDirectory {
@@ -48,6 +49,11 @@ struct ThreadStackPointer {
struct MemSpace {
/* trace node */
TraceTag tag;
+ /* mem usage info */
+ struct MemUsage kernspace_mem_usage;
+ struct MemUsage userspace_mem_usage;
+ struct MemUsage customized_mapping_mem_map;
+
/* task memory resources */
struct TopLevelPageDirectory pgdir; // [phy] vm pgtbl base address
struct TopLevelPageDirectory pgdir_riscv; // [phy] vm pgtbl base address
@@ -64,7 +70,7 @@ struct MemSpace {
struct Thread* thread_to_notify;
};
-struct MemSpace* alloc_memspace();
+struct MemSpace* alloc_memspace(char* name);
void free_memspace(struct MemSpace* pmemspace);
uintptr_t* load_memspace(struct MemSpace* pmemspace, char* img_start);
-struct ThreadStackPointer load_user_stack(struct MemSpace* pmemspace, char** argv);
\ No newline at end of file
+struct ThreadStackPointer load_user_stack(struct MemSpace* pmemspace, char** argv);
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/object_allocator.h b/Ubiquitous/XiZi_AIoT/softkernel/include/object_allocator.h
index a5865422a..52046905e 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/object_allocator.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/object_allocator.h
@@ -29,10 +29,12 @@ Modification:
*************************************************/
#pragma once
+#include "actracer_tag.h"
#include
#include
struct slab_state {
+ TraceTag owner_tag;
struct slab_state *prev, *next;
uint64_t bitmap;
uintptr_t refcount;
@@ -45,9 +47,10 @@ struct slab_allocator {
size_t slabsize;
uint64_t bitmap_empty;
struct slab_state *partial, *empty, *full;
+ char* name;
};
-void slab_init(struct slab_allocator*, size_t);
+void slab_init(struct slab_allocator*, size_t, char* name);
void slab_destroy(const struct slab_allocator*);
void* slab_alloc(struct slab_allocator*);
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h b/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h
index f6f9a2d7a..98cfdf61c 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h
@@ -49,8 +49,6 @@ Modification:
#define TOPLEVLE_PAGEDIR_SIZE sizeof(uintptr_t) * NUM_TOPLEVEL_PDE
-
-//#define PAGE_SHIFT (12)
#define _PAGE_PFN_SHIFT 10
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
#define PFN_PGD(x) ((x) << _PAGE_PFN_SHIFT)
@@ -87,5 +85,4 @@ void load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driv
void secondary_cpu_load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driver_tag);
extern struct XiziPageManager xizi_pager;
-bool module_pager_init(struct PagerRightGroup*);
-
+bool module_pager_init(struct PagerRightGroup*);
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/queue.h b/Ubiquitous/XiZi_AIoT/softkernel/include/queue.h
new file mode 100644
index 000000000..c1b267ecb
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/queue.h
@@ -0,0 +1,22 @@
+#pragma once
+#include
+
+typedef struct QueueNode {
+ uintptr_t key;
+ void* data;
+ struct QueueNode* next;
+} QueueNode;
+
+typedef struct Queue {
+ QueueNode* front;
+ QueueNode* rear;
+ int nr_ele;
+} Queue;
+
+void queue_init(Queue* queue);
+QueueNode* queue_front(Queue* queue);
+bool queue_is_empty(Queue* queue);
+bool dequeue(Queue* queue);
+bool enqueue(Queue* queue, uintptr_t key, void* data);
+
+void module_queue_factory_init(TraceTag* _softkernel_tag);
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/rbtree.h b/Ubiquitous/XiZi_AIoT/softkernel/include/rbtree.h
new file mode 100644
index 000000000..3ff77e1b9
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/rbtree.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include
+#include
+
+#include "actracer.h"
+
+#define RBTTREE_INSERT_SECC 0
+#define RBTTREE_INSERT_FAILED -1
+#define RBTTREE_INSERT_EXISTED -2
+
+#define RBTTREE_DELETE_SUCC 0
+#define RBTTREE_DELETE_FAILED -1
+
+// CLRS
+// Insertion and Deletion in a Red Black Tree
+enum rbt_type {
+ RED,
+ BLACK
+};
+
+typedef struct RbtNode {
+ uintptr_t key;
+ void* data;
+ struct RbtNode* left;
+ struct RbtNode* right;
+ struct RbtNode* parent;
+ enum rbt_type color;
+} RbtNode;
+
+typedef struct RbtTree {
+ RbtNode* root;
+ int nr_ele;
+} RbtTree;
+
+// return if the traverse needs to continue
+typedef bool(rbt_traverse_fn)(RbtNode* node, void* data);
+
+void rbtree_init(RbtTree* tree);
+int rbt_insert(RbtTree* tree, uintptr_t key, void* data);
+RbtNode* rbt_search(RbtTree* tree, uintptr_t key);
+int rbt_delete(RbtTree* tree, uintptr_t key);
+void rbt_traverse(RbtTree* tree, rbt_traverse_fn fn, void* data);
+
+void module_rbt_factory_init(TraceTag* _softkernel_tag);
+
+static inline bool rbt_is_empty(RbtTree* tree)
+{
+ return tree->nr_ele == 0;
+}
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/schedule_algo.h b/Ubiquitous/XiZi_AIoT/softkernel/include/schedule_algo.h
new file mode 100644
index 000000000..933731a5b
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/schedule_algo.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2020 AIIT XUOS Lab
+ * XiUOS is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+/**
+ * @file scheduler.h
+ * @brief scheduler algorithm declaration
+ * @version 3.0
+ * @author AIIT XUOS Lab
+ * @date 2023.08.25
+ */
+
+/*************************************************
+File name: scheduler.h
+Description: scheduler algorithm declaration
+Others:
+History:
+1. Date: 2023-08-28
+Author: AIIT XUOS Lab
+Modification:
+1. first version
+*************************************************/
+#pragma once
+
+#include "task.h"
+
+struct Thread* max_priority_runnable_task(void);
+struct Thread* round_robin_runnable_task(uint32_t priority);
+void recover_priority(void);
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/scheduler.h b/Ubiquitous/XiZi_AIoT/softkernel/include/scheduler.h
index 933731a5b..fd1adc3bd 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/scheduler.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/scheduler.h
@@ -1,36 +1,61 @@
-/*
- * Copyright (c) 2020 AIIT XUOS Lab
- * XiUOS is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
- * You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- */
-/**
- * @file scheduler.h
- * @brief scheduler algorithm declaration
- * @version 3.0
- * @author AIIT XUOS Lab
- * @date 2023.08.25
- */
-/*************************************************
-File name: scheduler.h
-Description: scheduler algorithm declaration
-Others:
-History:
-1. Date: 2023-08-28
-Author: AIIT XUOS Lab
-Modification:
-1. first version
-*************************************************/
#pragma once
+#include "actracer.h"
+#include "ksemaphore.h"
+#include "rbtree.h"
-#include "task.h"
+#define TASK_MAX_PRIORITY 32
+#define UNINIT_SNODE_ID 0
+typedef uintptr_t snode_id_t;
-struct Thread* max_priority_runnable_task(void);
-struct Thread* round_robin_runnable_task(uint32_t priority);
-void recover_priority(void);
\ No newline at end of file
+enum ThreadState {
+ NEVER_RUN = 0,
+ INIT,
+ READY,
+ RUNNING,
+ DEAD,
+ BLOCKED,
+ SLEEPING,
+ NR_STATE,
+
+ // follow state is temp for kernel use
+ TRANS_WAKING,
+};
+
+typedef struct ScheduleContext {
+ intptr_t remain_tick;
+ uint64_t run_time;
+ intptr_t unblock_signals;
+} ScheduleContext;
+
+typedef struct TaskSleepContext {
+ int64_t remain_ms;
+} TaskSleepContext;
+
+struct ScheduleNode {
+ struct Thread* pthd;
+ snode_id_t snode_id;
+ enum ThreadState state;
+ Queue state_trans_signal_queue;
+
+ ScheduleContext sched_context;
+ TaskSleepContext sleep_context;
+};
+
+struct Scheduler {
+ TraceTag tag;
+ RbtTree snode_state_pool[NR_STATE];
+ RbtTree state_trans_ref_map;
+ struct XiziSemaphorePool semaphore_pool;
+};
+
+extern struct Scheduler g_scheduler;
+
+bool init_schedule_node(struct ScheduleNode* snode, struct Thread* bind_thd);
+void enqueue_task_trans_state(struct Thread* thd, enum ThreadState state);
+#define THREAD_TRANS_STATE(thd, state) enqueue_task_trans_state(thd, state);
+
+bool task_trans_sched_state(struct ScheduleNode* snode, RbtTree* from_pool, RbtTree* to_pool, enum ThreadState target_state);
+void task_block(struct Thread* thd);
+void task_dead(struct Thread* thd);
+void task_into_ready(struct Thread* thd);
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/share_page.h b/Ubiquitous/XiZi_AIoT/softkernel/include/share_page.h
index bcb90dde7..1a31a9f8a 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/share_page.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/share_page.h
@@ -32,12 +32,13 @@ Modification:
#include
#include "actracer.h"
+#include "ksemaphore.h"
#include "list.h"
#include "task.h"
/// @brief userland session info copy
struct Session {
- int id;
+ uintptr_t id;
int capacity;
int head;
int tail;
@@ -48,7 +49,7 @@ struct Session {
#define CLIENT_SESSION_BACKEND(session) CONTAINER_OF(session, struct session_backend, client_side)
struct server_session {
- struct double_list_node node; // list_head of server task's ipc pipes
+ struct double_list_node node; // list node of server task's ipc pipes
uintptr_t buf_addr;
int capacity;
int head;
@@ -57,7 +58,7 @@ struct server_session {
};
struct client_session {
- struct double_list_node node; // list_head of client task's ipc pipes
+ struct double_list_node node; // list node of client task's ipc pipes
uintptr_t buf_addr;
int capacity;
bool closed;
@@ -72,6 +73,7 @@ struct session_backend {
struct Thread* client; // client of this pipe
struct Thread* server; // server of this pipe
+ sem_id_t client_sem_to_wait;
uintptr_t buf_kernel_addr;
};
@@ -90,3 +92,23 @@ struct XiziSharePageManager {
extern struct XiziSharePageManager xizi_share_page_manager;
int module_share_page_init(struct SharePageRightGroup* right_group);
+
+static inline void client_close_session(struct Thread* thd, struct client_session* cli_sess)
+{
+ assert(cli_sess != NULL);
+ struct session_backend* sess_backend = CLIENT_SESSION_BACKEND(cli_sess);
+ assert(sess_backend->client == thd);
+ assert(cli_sess->closed == false);
+ cli_sess->closed = true;
+ xizi_share_page_manager.delete_share_pages(sess_backend);
+}
+
+static inline void server_close_session(struct Thread* thd, struct server_session* svr_sess)
+{
+ assert(svr_sess != NULL);
+ struct session_backend* sess_backend = SERVER_SESSION_BACKEND(svr_sess);
+ assert(sess_backend->server == thd);
+ assert(svr_sess->closed == false);
+ svr_sess->closed = true;
+ xizi_share_page_manager.delete_share_pages(sess_backend);
+}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h
index 14e2ddc7e..0749088b7 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h
@@ -48,6 +48,9 @@ Modification:
#define SYSCALL_KILL 12 // kill the task by id
#define SYSCALL_SEMAPHORE 13 // semaphore related operations
+#define SYSCALL_SLEEP 14 // sleep
+
+#define SYSCALL_WAIT_SESSION 15
// clang-format on
#ifndef __ASSEMBLER__
@@ -66,6 +69,7 @@ typedef enum {
SYS_STATE_SHOW_CPU_INFO,
SYS_STATE_GET_CURRENT_TICK,
SYS_STATE_GET_CURRENT_SECOND,
+ SYS_STATE_SHOW_ACTREE,
} sys_state_option;
typedef enum {
@@ -74,6 +78,17 @@ typedef enum {
SYS_TASK_YIELD_BLOCK_IPC = 0x2,
} task_yield_reason;
+typedef enum {
+ SYS_MMAP_NORMAL = 0x0,
+ SYS_MMAP_CUSTOMIZE,
+} sys_mmap_type;
+
+typedef struct {
+ sys_mmap_type type;
+ uintptr_t attr;
+ bool is_dev;
+} sys_mmap_info;
+
typedef union {
struct {
uintptr_t memblock_start;
@@ -103,14 +118,17 @@ int sys_register_as_server(char* name);
int sys_connect_session(char* path, int capacity, struct Session* user_session);
int sys_poll_session(struct Session* userland_session_arr, int arr_capacity);
int sys_close_session(struct Thread* task, struct Session* session);
+int sys_wait_session(struct Session* userland_session);
int sys_exec(char* img_start, char* name, char** argv);
int sys_state(sys_state_option option, sys_state_info* info);
int sys_mmap(uintptr_t* vaddr, uintptr_t* paddr, int len, int is_dev);
+int sys_mmap_v2(uintptr_t* vaddr, uintptr_t* paddr, int len, sys_mmap_info* info);
int sys_register_irq(int irq_num, int irq_opcode);
int sys_unbind_irq_all(struct Thread* task);
int sys_unbind_irq(struct Thread* task, int irq_num);
int sys_semaphore(sys_sem_option op, int sem_id);
+int sys_sleep(intptr_t ms);
#endif
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h
index accfb513a..948ca3128 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h
+++ b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h
@@ -37,22 +37,19 @@ Modification:
#include "memspace.h"
#include "object_allocator.h"
#include "pagetable.h"
+#include "queue.h"
#include "share_page.h"
#include "spinlock.h"
+#include "scheduler.h"
+
#define TASK_CLOCK_TICK 50
#define TASK_MAX_PRIORITY 32
#define TASK_DEFAULT_PRIORITY 2
#define TASK_NAME_MAX_LEN 16
+#define SLEEP_MONITOR_CORE 0
-enum ProcState {
- INIT = 0,
- READY,
- RUNNING,
- DEAD,
- BLOCKED,
- NEVER_RUN,
-};
+typedef int tid_t;
/* Thread Control Block */
struct ThreadContext {
@@ -92,15 +89,15 @@ struct Thread {
/* task communication resources */
struct double_list_node cli_sess_listhead;
struct double_list_node svr_sess_listhead;
+ RbtTree cli_sess_map;
+ RbtTree svr_sess_map;
+ Queue sessions_to_be_handle;
+ Queue sessions_in_handle;
struct TraceTag server_identifier;
- bool advance_unblock;
+ bool advance_unblock; // @todo abandon
/* task schedule attributes */
- struct double_list_node node;
- enum ProcState state;
- int priority; // priority
- int remain_tick;
- int maxium_tick;
+ struct ScheduleNode snode;
};
struct SchedulerRightGroup {
@@ -108,13 +105,34 @@ struct SchedulerRightGroup {
struct TraceTag mmu_driver_tag;
};
+/* @todo task pool to maintain task lifetime and support fast task search */
+struct GlobalTaskPool {
+ RbtTree thd_ref_map;
+ struct double_list_node thd_listing_head;
+};
+
+struct TaskScheduler {
+};
+
+struct TaskLifecycleOperations {
+ /* new a task control block, checkout #sys_spawn for usage */
+ struct Thread* (*new_thread)(struct MemSpace* pmemspace);
+ /* free a task control block, this calls #free_user_pgdir to free all vitual spaces */
+ void (*free_thread)(struct Thread*);
+};
+
struct XiziTaskManager {
TraceTag tag;
/* thead schedule lists */
struct double_list_node task_list_head[TASK_MAX_PRIORITY]; /* list of task control blocks that are allocated */
struct double_list_node task_running_list_head;
struct double_list_node task_blocked_list_head;
+ struct double_list_node task_sleep_list_head;
struct XiziSemaphorePool semaphore_pool;
+ /* living task pool */
+ TraceTag task_pool_tag;
+ /* task lifecycle Ops */
+ TraceTag task_lifecycle_ops_tag;
/* mem allocator */
struct slab_allocator memspace_allocator;
@@ -124,13 +142,6 @@ struct XiziTaskManager {
/* init task manager */
void (*init)();
- /* new a task control block, checkout #sys_spawn for usage */
- struct Thread* (*new_task_cb)(struct MemSpace* pmemspace);
- /* free a task control block, this calls #free_user_pgdir to free all vitual spaces */
- void (*free_pcb)(struct Thread*);
- /* init a task control block, set name, remain_tick, state, cwd, priority, etc. */
- void (*task_set_default_schedule_attr)(struct Thread*);
-
/* use by task_scheduler, find next READY task, should be in locked */
struct Thread* (*next_runnable_task)(void);
/* function that's runing by kernel thread context, schedule use tasks */
@@ -139,9 +150,6 @@ struct XiziTaskManager {
/* handle task state */
/* call to yield current use task */
void (*task_yield_noschedule)(struct Thread* task, bool is_blocking);
- /* block and unblock task */
- void (*task_block)(struct double_list_node* head, struct Thread* task);
- void (*task_unblock)(struct Thread* task);
/* set task priority */
void (*set_cur_task_priority)(int priority);
};
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/init/softkernel_init.c b/Ubiquitous/XiZi_AIoT/softkernel/init/softkernel_init.c
index 53e3d4291..d10f5bac6 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/init/softkernel_init.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/init/softkernel_init.c
@@ -31,10 +31,14 @@ Modification:
#include "assert.h"
#include "log.h"
+#include "rbtree.h"
#include "task.h"
-bool softkernel_init(struct TraceTag* _hardkernel_tag, struct TraceTag* _softkernel_tag)
+bool softkernel_init(TraceTag* _hardkernel_tag, struct TraceTag* _softkernel_tag)
{
+ module_rbt_factory_init(_softkernel_tag);
+ module_queue_factory_init(_softkernel_tag);
+
struct TraceTag server_identifier_owner;
CreateResourceTag(&server_identifier_owner, _softkernel_tag, "server-identifier", TRACER_OWNER, NULL);
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c
index d19f63d67..c6c6a5895 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/main.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c
@@ -59,6 +59,7 @@ int main(void)
if (cpu_id == 0) {
/* init memory management first */
+
module_phymem_init(); // init buddy management system
/* init tracer system */
sys_tracer_init();
@@ -95,10 +96,17 @@ int main(void)
}
/* start first task */
+#ifndef __riscv
char* init_task_param[2] = { "/app/shell", 0 };
sys_spawn((char*)_binary_init_start, "shell", init_task_param);
char* fs_server_task_param[2] = { "/app/fs_server", 0 };
sys_spawn((char*)_binary_default_fs_start, "memfs", fs_server_task_param);
+#else
+ char* fs_server_task_param[2] = { "/app/fs_server", 0 };
+ sys_spawn((char*)_binary_default_fs_start, "memfs", fs_server_task_param);
+ char* init_task_param[2] = { "/app/shell", 0 };
+ sys_spawn((char*)_binary_init_start, "shell", init_task_param);
+#endif
}
/* start scheduler */
struct SchedulerRightGroup scheduler_rights;
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c
index 97817851a..eda38cf46 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c
@@ -31,6 +31,7 @@ Modification:
#include "buddy.h"
#include "kalloc.h"
#include "log.h"
+#include "pagetable.h"
static void _buddy_split_page(struct KPage* page, uintptr_t low_order, uintptr_t high_order, struct KFreeList* list)
{
@@ -77,8 +78,13 @@ static struct KPage* KBuddyPagesAlloc(struct KBuddy* pbuddy, int nPages)
int i = 0, order = 0;
// find order
+#if defined(__GNUC__)
+ // see: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
+ order = nPages ? (sizeof(int) * 8 - __builtin_clz(nPages) - 1) + !!(__builtin_popcount(nPages) != 1) : 0;
+#else
for (order = 0; (FREE_LIST_INDEX(order)) < nPages; order++)
;
+#endif
// find the free page list
for (i = order; i < MAX_BUDDY_ORDER; i++) {
@@ -161,7 +167,8 @@ bool KBuddyInit(struct KBuddy* pbuddy, uintptr_t mem_start, uintptr_t mem_end)
// total number of free pages
pbuddy->n_pages = (pbuddy->mem_end - (uintptr_t)pbuddy->mem_start) >> LEVEL4_PTE_SHIFT;
- memset(pbuddy->pages, 0, pbuddy->n_pages);
+ memset(pbuddy->pages, 0, pbuddy->n_pages * sizeof(struct KPage));
+ // memset(pbuddy->pages, 0, pbuddy->n_pages);
// init each free page list from 2^0 to 2^8
for (; i < MAX_BUDDY_ORDER; i++) {
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c
index 39b2138f1..dbb300e5f 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c
@@ -30,10 +30,12 @@ Modification:
#include "kalloc.h"
#include "assert.h"
+#include "memlayout.h"
+#include "pagetable.h"
+
#include "actracer.h"
#include "buddy.h"
-
struct KBuddy kern_virtmem_buddy;
struct KBuddy user_phy_freemem_buddy;
@@ -73,11 +75,37 @@ char* kalloc(uintptr_t size)
return mem_alloc;
}
+void* kalloc_by_ownership(TraceTag owner, uintptr_t size)
+{
+ void* new_mem = kalloc(size);
+ if (NULL == new_mem) {
+ return NULL;
+ }
+
+ struct MemUsage* usage = GetSysObject(struct MemUsage, &owner);
+ if (0 != rbt_insert(&usage->mem_block_map, (uintptr_t)new_mem, NULL)) {
+ kfree(new_mem);
+ return NULL;
+ }
+ return new_mem;
+}
+
bool kfree(char* vaddr)
{
return KBuddyFree(&kern_virtmem_buddy, V2P_WO(vaddr));
}
+bool kfree_by_ownership(TraceTag owner, void* vaddr)
+{
+ struct MemUsage* usage = GetSysObject(struct MemUsage, &owner);
+ // DEBUG("%p %p %p %p\n", usage, usage->mem_block_root, usage->tag, vaddr);
+ RbtNode* node = rbt_search(&usage->mem_block_map, (uintptr_t)vaddr);
+ assert(NULL != node);
+ assert(0 == rbt_delete(&usage->mem_block_map, node->key));
+
+ return kfree(vaddr);
+}
+
bool raw_kfree(char* paddr)
{
return KBuddyFree(&kern_virtmem_buddy, paddr);
@@ -92,11 +120,36 @@ char* raw_alloc(size_t size)
return mem_alloc;
}
+void* raw_alloc_by_ownership(TraceTag owner, uintptr_t size)
+{
+ void* new_mem = raw_alloc(size);
+ if (!new_mem) {
+ return NULL;
+ }
+
+ struct MemUsage* usage = GetSysObject(struct MemUsage, &owner);
+ if (0 != rbt_insert(&usage->mem_block_map, (uintptr_t)new_mem, NULL)) {
+ raw_free(new_mem);
+ return NULL;
+ }
+ return new_mem;
+}
+
bool raw_free(char* paddr)
{
return KBuddyFree(&user_phy_freemem_buddy, paddr);
}
+bool raw_free_by_ownership(TraceTag owner, void* vaddr)
+{
+ struct MemUsage* usage = GetSysObject(struct MemUsage, &owner);
+ RbtNode* node = rbt_search(&usage->mem_block_map, (uintptr_t)vaddr);
+ assert(NULL != node);
+ assert(0 == rbt_delete(&usage->mem_block_map, node->key));
+
+ return raw_free(vaddr);
+}
+
void show_phymem_info()
{
KFreePagesInfo(&user_phy_freemem_buddy);
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/object_allocator.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/object_allocator.c
index b79e52ac6..dd9ac5769 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/memory/object_allocator.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/object_allocator.c
@@ -32,6 +32,7 @@ Modification:
#include "assert.h"
#include "kalloc.h"
#include "object_allocator.h"
+#include "pagetable.h"
#define BITMAP_BITS_EMPTY_FULL ((uint64_t)0)
#define BITMAP_FIRST_BIT ((uint64_t)1)
@@ -44,10 +45,10 @@ Modification:
#define LOWLEVEL_ALLOC(size) kalloc(size)
#define LOWLEVEL_FREE(ptr) kfree(ptr)
-#define ARENA_SIZE_PER_INCREASE PAGE_SIZE
+#define ARENA_SIZE_PER_INCREASE (2 * PAGE_SIZE)
#define MAX_NR_ELEMENT_PER_SLABPAGE 64
-void slab_init(struct slab_allocator* const allocator, const size_t element_size)
+void slab_init(struct slab_allocator* const allocator, const size_t element_size, char* name)
{
if (allocator == NULL) {
panic("init a NULL slab_allocator\n");
@@ -63,8 +64,11 @@ void slab_init(struct slab_allocator* const allocator, const size_t element_size
allocator->nr_elements = allocator->nr_elements > MAX_NR_ELEMENT_PER_SLABPAGE ? MAX_NR_ELEMENT_PER_SLABPAGE : allocator->nr_elements;
allocator->bitmap_empty = ~BITMAP_BITS_EMPTY_FULL >> (MAX_NR_ELEMENT_PER_SLABPAGE - allocator->nr_elements);
-
allocator->partial = allocator->empty = allocator->full = NULL;
+
+ if (name) {
+ allocator->name = name;
+ }
}
void* slab_alloc(struct slab_allocator* const allocator)
@@ -107,7 +111,7 @@ void* slab_alloc(struct slab_allocator* const allocator)
/* achieve slab from outer arena */
allocator->partial = (struct slab_state*)LOWLEVEL_ALLOC(allocator->slabsize);
if (UNLIKELY(allocator->partial == NULL)) {
- ERROR("no enough memory\n");
+ ERROR("slab %s: no enough memory\n", allocator->name);
return allocator->partial = NULL;
}
allocator->partial->prev = allocator->partial->next = NULL;
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c
index 53404786f..41e956f8c 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c
@@ -143,6 +143,20 @@ static bool _map_user_pages(struct MemSpace* pmemspace, uintptr_t vaddr, uintptr
return _map_pages(pmemspace->pgdir.pd_addr, vaddr, paddr, (intptr_t)len, mem_attr);
}
+bool _map_customizable_page(struct MemSpace* pmemspace, uintptr_t vaddr, uintptr_t paddr, int len, uintptr_t attr)
+{
+ if (len < 0) {
+ return false;
+ }
+
+ if (UNLIKELY(vaddr >= USER_MEM_TOP)) {
+ ERROR("mapping kernel space.\n");
+ return false;
+ }
+
+ return _map_pages(pmemspace->pgdir.pd_addr, vaddr, paddr, (intptr_t)len, attr);
+}
+
/// assume that a user pagedir is allocated from [0, size)
/// if new_size > old_size, allocate more space,
/// if old_size > new_size, free extra space, to avoid unnecessary alloc/free.
@@ -160,7 +174,8 @@ static uintptr_t _resize_user_pgdir(struct MemSpace* pmemspace, uintptr_t old_si
uintptr_t cur_size = ALIGNUP(old_size, PAGE_SIZE);
uintptr_t size_needed = ALIGNUP(new_size, PAGE_SIZE) - cur_size;
- char* new_page = kalloc(size_needed);
+ // char* new_page = kalloc(size_needed);
+ char* new_page = kalloc_by_ownership(pmemspace->kernspace_mem_usage.tag, size_needed);
if (new_page == NULL) {
ERROR("No memory\n");
return cur_size;
@@ -169,7 +184,6 @@ static uintptr_t _resize_user_pgdir(struct MemSpace* pmemspace, uintptr_t old_si
if (!xizi_pager.map_pages(pmemspace, cur_size, V2P(new_page), size_needed, false)) {
return cur_size;
}
- CreateResourceTag(NULL, &pmemspace->tag, NULL, TRACER_MEM_FROM_BUDDY_AC_RESOURCE, V2P_WO(new_page));
return new_size;
}
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c
index 68adee8fa..9dc3f02dd 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c
@@ -166,6 +166,19 @@ static bool _map_user_pages(struct MemSpace* pmemspace, uintptr_t vaddr, uintptr
return true;
}
+bool _map_customizable_page(struct MemSpace* pmemspace, uintptr_t vaddr, uintptr_t paddr, int len, uintptr_t attr)
+{
+ if (len < 0) {
+ return false;
+ }
+
+ if (UNLIKELY(vaddr >= USER_MEM_TOP)) {
+ ERROR("mapping kernel space.\n");
+ return false;
+ }
+
+ return _map_pages(pmemspace->pgdir.pd_addr, vaddr, paddr, (intptr_t)len, attr);
+}
/// assume that a user pagedir is allocated from [0, size)
/// if new_size > old_size, allocate more space,
/// if old_size > new_size, free extra space, to avoid unnecessary alloc/free.
@@ -183,7 +196,8 @@ static uintptr_t _resize_user_pgdir(struct MemSpace* pmemspace, uintptr_t old_si
uintptr_t cur_size = ALIGNUP(old_size, PAGE_SIZE);
uintptr_t size_needed = ALIGNUP(new_size, PAGE_SIZE) - cur_size;
- char* new_page = kalloc(size_needed);
+ // char* new_page = kalloc(size_needed);
+ char* new_page = kalloc_by_ownership(pmemspace->kernspace_mem_usage.tag, size_needed);
if (new_page == NULL) {
ERROR("No memory\n");
return cur_size;
@@ -192,7 +206,7 @@ static uintptr_t _resize_user_pgdir(struct MemSpace* pmemspace, uintptr_t old_si
if (!xizi_pager.map_pages(pmemspace, cur_size, V2P(new_page), size_needed, false)) {
return cur_size;
}
- CreateResourceTag(NULL, &pmemspace->tag, NULL, TRACER_MEM_FROM_BUDDY_AC_RESOURCE, V2P_WO(new_page));
+
return new_size;
}
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c
index a728cfb3f..12ecdf2a8 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c
@@ -44,7 +44,7 @@ static struct slab_allocator* SessionAllocator()
static bool init = false;
static struct slab_allocator session_slab;
if (!init) {
- slab_init(&session_slab, sizeof(struct session_backend));
+ slab_init(&session_slab, sizeof(struct session_backend), "SessionAllocator");
}
return &session_slab;
}
@@ -207,11 +207,34 @@ void unmap_task_share_pages(struct Thread* task, const uintptr_t task_vaddr, con
static int next_session_id = 1;
struct session_backend* create_share_pages(struct Thread* client, struct Thread* server, const int capacity)
{
+
/* alloc session backend */
struct session_backend* session_backend = (struct session_backend*)slab_alloc(SessionAllocator());
if (UNLIKELY(session_backend == NULL)) {
return NULL;
}
+ session_backend->session_id = next_session_id++;
+
+ if (0 != rbt_insert(&client->cli_sess_map, session_backend->session_id, &session_backend->client_side)) {
+ DEBUG("Rbt of %s no memory\n", client->name);
+ slab_free(SessionAllocator(), session_backend);
+ return NULL;
+ }
+
+ if (0 != rbt_insert(&server->svr_sess_map, session_backend->session_id, &session_backend->server_side)) {
+ DEBUG("Rbt of %s no memory\n", server->name);
+ rbt_delete(&client->cli_sess_map, session_backend->session_id);
+ slab_free(SessionAllocator(), session_backend);
+ return NULL;
+ }
+
+ sem_id_t new_sem_id = ksemaphore_alloc(&xizi_task_manager.semaphore_pool, 0);
+ if (new_sem_id == INVALID_SEM_ID) {
+ ERROR("No memory to alloc sem\n");
+ slab_free(SessionAllocator(), session_backend);
+ return NULL;
+ }
+ session_backend->client_sem_to_wait = new_sem_id;
int true_capacity = ALIGNUP(capacity, PAGE_SIZE);
int nr_pages = true_capacity / PAGE_SIZE;
@@ -220,6 +243,7 @@ struct session_backend* create_share_pages(struct Thread* client, struct Thread*
if (UNLIKELY(kern_vaddr == (uintptr_t)NULL)) {
ERROR("No memory for session\n");
slab_free(SessionAllocator(), session_backend);
+ ksemaphore_free(&xizi_task_manager.semaphore_pool, new_sem_id);
return NULL;
}
@@ -229,6 +253,7 @@ struct session_backend* create_share_pages(struct Thread* client, struct Thread*
if (UNLIKELY(client_vaddr == (uintptr_t)NULL)) {
kfree((char*)kern_vaddr);
slab_free(SessionAllocator(), session_backend);
+ ksemaphore_free(&xizi_task_manager.semaphore_pool, new_sem_id);
return NULL;
}
@@ -238,11 +263,11 @@ struct session_backend* create_share_pages(struct Thread* client, struct Thread*
unmap_task_share_pages(client, client_vaddr, nr_pages);
kfree((char*)kern_vaddr);
slab_free(SessionAllocator(), session_backend);
+ ksemaphore_free(&xizi_task_manager.semaphore_pool, new_sem_id);
return NULL;
}
/* build session_backend */
- session_backend->session_id = next_session_id++;
session_backend->buf_kernel_addr = kern_vaddr;
session_backend->nr_pages = nr_pages;
session_backend->client = client;
@@ -286,24 +311,39 @@ int delete_share_pages(struct session_backend* session_backend)
// close ssesion in server's perspective
if (session_backend->server_side.closed && session_backend->server != NULL) {
xizi_share_page_manager.unmap_task_share_pages(session_backend->server, session_backend->server_side.buf_addr, session_backend->nr_pages);
- doubleListDel(&session_backend->server_side.node);
- session_backend->server->memspace->mem_size -= session_backend->nr_pages * PAGE_SIZE;
- session_backend->server = NULL;
+
+ ERROR_FREE
+ {
+ assert(0 == rbt_delete(&session_backend->server->svr_sess_map, session_backend->session_id));
+ doubleListDel(&session_backend->server_side.node);
+ session_backend->server->memspace->mem_size -= session_backend->nr_pages * PAGE_SIZE;
+ session_backend->server = NULL;
+ }
}
// close ssesion in client's perspective
if (session_backend->client_side.closed && session_backend->client != NULL) {
xizi_share_page_manager.unmap_task_share_pages(session_backend->client, session_backend->client_side.buf_addr, session_backend->nr_pages);
- doubleListDel(&session_backend->client_side.node);
- session_backend->client->memspace->mem_size -= session_backend->nr_pages * PAGE_SIZE;
- session_backend->client = NULL;
+
+ ERROR_FREE
+ {
+ assert(0 == rbt_delete(&session_backend->client->cli_sess_map, session_backend->session_id));
+ doubleListDel(&session_backend->client_side.node);
+ session_backend->client->memspace->mem_size -= session_backend->nr_pages * PAGE_SIZE;
+ session_backend->client = NULL;
+
+ assert(ksemaphore_free(&xizi_task_manager.semaphore_pool, session_backend->client_sem_to_wait));
+ }
}
/* free seesion backend */
if (session_backend->server_side.closed && session_backend->client_side.closed) {
- assert(session_backend->client == NULL && session_backend->server == NULL);
- kfree((void*)session_backend->buf_kernel_addr);
- slab_free(SessionAllocator(), (void*)session_backend);
+ ERROR_FREE
+ {
+ assert(session_backend->client == NULL && session_backend->server == NULL);
+ assert(kfree((void*)session_backend->buf_kernel_addr));
+ slab_free(SessionAllocator(), (void*)session_backend);
+ }
}
return 0;
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile
index 4adbb947d..d85d1e220 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile
@@ -1,6 +1,7 @@
SRC_FILES := syscall.c \
sys_spawn.c \
sys_thread.c \
+ sys_sleep.c \
sys_yield.c \
sys_register_as_server.c \
sys_connect_session.c \
@@ -11,6 +12,7 @@ SRC_FILES := syscall.c \
sys_state.c \
sys_mmap.c \
sys_kill.c \
- sys_semaphore.c
+ sys_semaphore.c \
+ sys_wait_session.c
include $(KERNEL_ROOT)/compiler.mk
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_close_session.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_close_session.c
index 24f7ea996..a1e35cdd0 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_close_session.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_close_session.c
@@ -46,35 +46,48 @@ int sys_close_session(struct Thread* cur_task, struct Session* session)
return -1;
}
- /* check if session is a client one or a server one */
struct session_backend* session_backend = NULL;
- struct client_session* client_session = NULL;
- DOUBLE_LIST_FOR_EACH_ENTRY(client_session, &cur_task->cli_sess_listhead, node)
- {
- if ((uintptr_t)session->buf == client_session->buf_addr) {
- session_backend = CLIENT_SESSION_BACKEND(client_session);
- assert(session_backend->client == cur_task);
- assert(client_session->closed == false);
- client_session->closed = true;
- xizi_share_page_manager.delete_share_pages(session_backend);
- break;
+ /* check if session is a client one or a server one */
+ RbtNode* client_session_node = rbt_search(&cur_task->cli_sess_map, session->id);
+ if (client_session_node != NULL) {
+ struct client_session* client_session = (struct client_session*)client_session_node->data;
+ if (CLIENT_SESSION_BACKEND(client_session)->session_id != session->id || //
+ client_session->buf_addr != (uintptr_t)session->buf) {
+ ERROR("Error closing session from %s: Invalid session\n", cur_task->name);
+ return -1;
+ }
+
+ /* close client session */
+ session_backend = CLIENT_SESSION_BACKEND(client_session);
+ assert(session_backend->client == cur_task);
+ assert(client_session->closed == false);
+ client_session->closed = true;
+ xizi_share_page_manager.delete_share_pages(session_backend);
+
+ struct Thread* server_to_info = session_backend->server;
+ if (!enqueue(&server_to_info->sessions_to_be_handle, 0, (void*)&session_backend->server_side)) {
+ // @todo fix memory leak
+ } else {
+ assert(!queue_is_empty(&server_to_info->sessions_to_be_handle));
+ THREAD_TRANS_STATE(server_to_info, TRANS_WAKING);
}
}
- if (UNLIKELY(session_backend == NULL)) {
- struct server_session* server_session = NULL;
- DOUBLE_LIST_FOR_EACH_ENTRY(server_session, &cur_task->svr_sess_listhead, node)
- {
- if ((uintptr_t)session->buf == server_session->buf_addr) {
- session_backend = SERVER_SESSION_BACKEND(server_session);
- assert(session_backend->server == cur_task);
- assert(server_session->closed == false);
- server_session->closed = true;
- xizi_share_page_manager.delete_share_pages(session_backend);
- break;
- }
+ RbtNode* server_session_node = rbt_search(&cur_task->svr_sess_map, session->id);
+ if (server_session_node != NULL) {
+ struct server_session* server_session = (struct server_session*)server_session_node->data;
+ if (SERVER_SESSION_BACKEND(server_session)->session_id != session->id || //
+ server_session->buf_addr != (uintptr_t)session->buf) {
+ ERROR("Error closing session from %s: Invalid session\n", cur_task->name);
+ return -1;
}
+
+ session_backend = SERVER_SESSION_BACKEND(server_session);
+ assert(session_backend->server == cur_task);
+ assert(server_session->closed == false);
+ server_session->closed = true;
+ xizi_share_page_manager.delete_share_pages(session_backend);
}
/* close this session */
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c
index af053b420..8c3aab27c 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c
@@ -40,11 +40,11 @@ int sys_exit(struct Thread* ptask)
{
assert(ptask != NULL);
ptask->dead = true;
- // free that task straightly if it's a blocked task
- if (ptask->state == BLOCKED) {
- xizi_task_manager.free_pcb(ptask);
+ // awake the task if it's a blocked task
+ if (ptask->snode.state == BLOCKED || ptask->snode.state == SLEEPING) {
+ THREAD_TRANS_STATE(ptask, TRANS_WAKING);
}
// yield current task in case it wants to exit itself
- xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false);
+ THREAD_TRANS_STATE(cur_cpu()->task, READY);
return 0;
}
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_kill.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_kill.c
index 9510ca226..8a1b603c9 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_kill.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_kill.c
@@ -27,53 +27,37 @@ Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
+#include "task.h"
#include "trap_common.h"
-#include "task.h"
+static bool kill_succ;
+
+extern int sys_exit(struct Thread* ptask);
+static bool kill_task(RbtNode* node, void* id)
+{
+ struct ScheduleNode* snode = (struct ScheduleNode*)node->data;
+ struct Thread* thd = snode->pthd;
+ tid_t target_id = *(tid_t*)id;
+
+ if (thd->tid == target_id) {
+ sys_exit(thd);
+ kill_succ = true;
+ return false;
+ }
+
+ return true;
+}
extern int sys_exit(struct Thread* task);
int sys_kill(int id)
{
- struct Thread* task = NULL;
- // check if task is a running one
- DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_running_list_head, node)
- {
- if (task->tid == id) {
- sys_exit(task);
- return 0;
- }
+ kill_succ = false;
+ for (int pool_id = 0; pool_id < NR_STATE; pool_id++) {
+ rbt_traverse(&g_scheduler.snode_state_pool[pool_id], kill_task, (void*)&id);
}
- // check if task is a blocking one
- DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_blocked_list_head, node)
- {
- if (task->tid == id) {
- sys_exit(task);
- return 0;
- }
+ if (kill_succ) {
+ return 0;
}
-
- struct ksemaphore* sem = NULL;
- DOUBLE_LIST_FOR_EACH_ENTRY(sem, &xizi_task_manager.semaphore_pool.sem_list_guard, sem_list_node)
- {
- task = NULL;
- DOUBLE_LIST_FOR_EACH_ENTRY(task, &sem->wait_list_guard, node)
- {
- sys_exit(task);
- return 0;
- }
- }
-
- // check if task is a ready one
- for (int prio = 0; prio < TASK_MAX_PRIORITY; prio++) {
- DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[prio], node)
- {
- if (task->tid == id) {
- sys_exit(task);
- return 0;
- }
- }
- }
-
return -1;
}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_mmap.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_mmap.c
index becf0b9d7..6cd460257 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_mmap.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_mmap.c
@@ -54,19 +54,108 @@ int sys_mmap(uintptr_t* vaddr, uintptr_t* paddr, int len, int is_dev)
}
} else {
uintptr_t load_vaddr = *vaddr;
- char* new_paddr = raw_alloc(true_len);
+ char* new_paddr = raw_alloc_by_ownership(cur_task->memspace->userspace_mem_usage.tag, true_len);
if (new_paddr == NULL) {
return -1;
}
if (xizi_share_page_manager.task_map_pages(cur_task, load_vaddr, (uintptr_t)new_paddr, true_len / PAGE_SIZE, false) == (uintptr_t)NULL) {
- raw_free(new_paddr);
+ raw_free_by_ownership(cur_task->memspace->userspace_mem_usage.tag, new_paddr);
return -1;
}
- CreateResourceTag(NULL, &cur_task->memspace->tag, NULL, TRACER_MEM_FROM_BUDDY_AC_RESOURCE, new_paddr);
+ CreateResourceTag(NULL, &cur_task->memspace->tag, "USER_MEMORY", TRACER_MEM_SIGNATURE, new_paddr);
*paddr = (uintptr_t)new_paddr;
}
cur_task->memspace->mem_size += true_len;
*vaddr = *vaddr + true_len;
return 0;
+}
+
+extern bool _map_customizable_page(struct MemSpace* pmemspace, uintptr_t vaddr, uintptr_t paddr, int len, uintptr_t attr);
+int sys_mmap_v2(uintptr_t* vaddr, uintptr_t* paddr, int len, sys_mmap_info* info)
+{
+ struct Thread* cur_task = cur_cpu()->task;
+ assert(cur_task != NULL);
+
+ if (vaddr == NULL) {
+ ERROR("Invalid vaddr from %s\n", cur_task->name);
+ }
+
+ int true_len = ALIGNUP(len, PAGE_SIZE);
+
+ sys_mmap_type type = info->type;
+ uintptr_t vaddr_to_map = *vaddr;
+ if (type == SYS_MMAP_CUSTOMIZE) {
+ if (paddr == NULL || *paddr == (uintptr_t)NULL || vaddr_to_map == (uintptr_t)NULL) {
+ ERROR("Customized mapping from %s must have vaddr(%p) and paddr(%p)\n", cur_task->name, vaddr, paddr);
+ return -1;
+ }
+ uintptr_t paddr_to_map = *paddr;
+
+ TraceTag mem_signature_tag;
+ if (!CreateResourceTag(&mem_signature_tag, &cur_task->memspace->tag, "CUSTOMIZED_MEMORY", TRACER_MEM_SIGNATURE, (void*)vaddr)) {
+ ERROR("Sign memory signature failed from %s\n", cur_task->name);
+ return -1;
+ }
+
+ if (!_map_customizable_page(cur_task->memspace, vaddr_to_map, paddr_to_map, len, info->attr)) {
+ ERROR("%s mapping page failed(Short of memory)\n", cur_task->name);
+ DeleteResource(&mem_signature_tag, &cur_task->memspace->tag);
+ return -1;
+ }
+
+ return 0;
+ }
+
+ if (type == SYS_MMAP_NORMAL) {
+ bool is_dev = info->is_dev;
+
+ if (*paddr != (uintptr_t)NULL) {
+
+ if (paddr == NULL || *paddr == (uintptr_t)NULL || vaddr_to_map == (uintptr_t)NULL) {
+ ERROR("Invalid mapping from %s\n", cur_task->name);
+ return -1;
+ }
+
+ uintptr_t paddr_to_map = *paddr;
+ if (paddr_to_map >= PHY_MEM_BASE && paddr_to_map < PHY_MEM_STOP && cur_task->tid > 2) {
+ ERROR("mapping invalid memory: 0x%p by %d\n", paddr_to_map, cur_task->tid);
+ return -1;
+ }
+
+ if (xizi_share_page_manager.task_map_pages(cur_task, vaddr_to_map, paddr_to_map, true_len / PAGE_SIZE, is_dev) == (uintptr_t)NULL) {
+ ERROR("%s mapping page failed(Short of memory)\n", cur_task->name);
+ return -1;
+ }
+
+ } else {
+ char* new_paddr = raw_alloc_by_ownership(cur_task->memspace->userspace_mem_usage.tag, true_len);
+ if (new_paddr == NULL) {
+ ERROR("Alloc dynamic memory failed\n");
+ return -1;
+ }
+
+ TraceTag mem_signature_tag;
+ if (!CreateResourceTag(&mem_signature_tag, &cur_task->memspace->tag, "USER_MEMORY", TRACER_MEM_SIGNATURE, new_paddr)) {
+ raw_free_by_ownership(cur_task->memspace->userspace_mem_usage.tag, new_paddr);
+ ERROR("Sign memory signature failed from %s\n", cur_task->name);
+ return -1;
+ }
+
+ if (xizi_share_page_manager.task_map_pages(cur_task, vaddr_to_map, (uintptr_t)new_paddr, true_len / PAGE_SIZE, false) == (uintptr_t)NULL) {
+ raw_free_by_ownership(cur_task->memspace->userspace_mem_usage.tag, new_paddr);
+ DeleteResource(&mem_signature_tag, &cur_task->memspace->tag);
+ return -1;
+ }
+
+ // assign new_paddr back to user
+ *paddr = (uintptr_t)new_paddr;
+ }
+
+ cur_task->memspace->mem_size += true_len;
+ *vaddr = *vaddr + true_len;
+ return 0;
+ }
+
+ return -1;
}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c
index 55451238e..702594fce 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c
@@ -34,14 +34,7 @@ Modification:
#include "syscall.h"
#include "task.h"
-#define IPCSESSION_MSG(session) ((struct IpcMsg*)((char*)((session)->buf) + (session)->head))
-
-static inline bool is_msg_needed(struct IpcMsg* msg)
-{
- assert(msg != NULL);
- return msg->header.magic == IPC_MSG_MAGIC && msg->header.valid == 1 && msg->header.done == 0 && msg->header.handling == 0;
-}
-
+extern bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, sem_id_t sem_id);
int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
{
struct Thread* cur_task = cur_cpu()->task;
@@ -50,46 +43,40 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
return -1;
}
- struct double_list_node* cur_node = NULL;
- struct server_session* server_session = NULL;
-
/* update old sessions */
- for (int i = 0; i < arr_capacity; i++) {
- if (UNLIKELY(userland_session_arr[i].buf == NULL)) {
- break;
+ int cur_userland_idx = 0;
+ while (!queue_is_empty(&cur_task->sessions_in_handle)) {
+ struct server_session* server_session = (struct server_session*)queue_front(&cur_task->sessions_in_handle)->data;
+ assert(server_session != NULL);
+
+ // wrong session info
+ if (userland_session_arr[cur_userland_idx].id != SERVER_SESSION_BACKEND(server_session)->session_id || //
+ (uintptr_t)userland_session_arr[cur_userland_idx].buf != server_session->buf_addr) {
+ ERROR("mismatched old session from %s, user buf: %x, server buf: %x\n", cur_task->name, userland_session_arr[cur_userland_idx].buf, server_session->buf_addr);
+ } else {
+ // update session_backend
+ ksemaphore_signal(&xizi_task_manager.semaphore_pool, SERVER_SESSION_BACKEND(server_session)->client_sem_to_wait);
+
+ server_session->head = userland_session_arr[cur_userland_idx].head;
+ server_session->tail = userland_session_arr[cur_userland_idx].tail;
+ userland_session_arr[cur_userland_idx].buf = NULL;
+ userland_session_arr[cur_userland_idx].id = -1;
}
- cur_node = cur_task->svr_sess_listhead.next;
- server_session = CONTAINER_OF(cur_node, struct server_session, node);
- if (UNLIKELY(server_session->buf_addr != (uintptr_t)userland_session_arr[i].buf)) {
- ERROR("mismatched old session addr, user buf: %x, server buf: %x\n", userland_session_arr[i].buf, server_session->buf_addr);
- return -1;
- }
- // update session_backend
- // if current session is handled
- if (server_session->head != userland_session_arr[i].head) {
- struct Thread* client = SERVER_SESSION_BACKEND(server_session)->client;
- if (client->state == BLOCKED) {
- xizi_task_manager.task_unblock(client);
- } else {
- client->advance_unblock = true;
- }
- }
- server_session->head = userland_session_arr[i].head;
- server_session->tail = userland_session_arr[i].tail;
- doubleListDel(cur_node);
- doubleListAddOnBack(cur_node, &cur_task->svr_sess_listhead);
+
+ assert(dequeue(&cur_task->sessions_in_handle));
+ cur_userland_idx++;
}
/* poll with new sessions */
- int nr_sessions_need_to_handle = 0;
- bool has_middle_delete = false;
- int session_idx = 0;
- DOUBLE_LIST_FOR_EACH_ENTRY(server_session, &cur_task->svr_sess_listhead, node)
- {
- if (session_idx >= arr_capacity) {
+ cur_userland_idx = 0;
+ while (!queue_is_empty(&cur_task->sessions_to_be_handle)) {
+ if (cur_userland_idx == arr_capacity) {
break;
}
+ struct server_session* server_session = (struct server_session*)queue_front(&cur_task->sessions_to_be_handle)->data;
+ assert(server_session != NULL);
+
if (SERVER_SESSION_BACKEND(server_session)->client_side.closed) {
// client had closed it, then server will close it too
struct session_backend* session_backend = SERVER_SESSION_BACKEND(server_session);
@@ -98,12 +85,11 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
assert(server_session->closed == false);
server_session->closed = true;
xizi_share_page_manager.delete_share_pages(session_backend);
- // signal that there is a middle deletion of session
- has_middle_delete = true;
- break;
+ dequeue(&cur_task->sessions_to_be_handle);
+ continue;
}
- userland_session_arr[session_idx] = (struct Session) {
+ userland_session_arr[cur_userland_idx] = (struct Session) {
.buf = (void*)server_session->buf_addr,
.capacity = server_session->capacity,
.head = server_session->head,
@@ -111,25 +97,22 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
.id = SERVER_SESSION_BACKEND(server_session)->session_id,
};
- struct IpcMsg* msg = IPCSESSION_MSG(&userland_session_arr[session_idx]);
- if (msg != NULL && is_msg_needed(msg)) {
- nr_sessions_need_to_handle++;
+ if (!enqueue(&cur_task->sessions_in_handle, 0, (void*)server_session)) {
+ userland_session_arr[cur_userland_idx].buf = NULL;
+ userland_session_arr[cur_userland_idx].id = 0;
+ break;
}
-
- session_idx++;
+ assert(dequeue(&cur_task->sessions_to_be_handle));
+ cur_userland_idx++;
}
- if (session_idx < arr_capacity) {
- userland_session_arr[session_idx].buf = NULL;
- if (!has_middle_delete && nr_sessions_need_to_handle == 0) {
- if (cur_task->advance_unblock) {
- cur_task->advance_unblock = false;
- } else {
- xizi_task_manager.task_yield_noschedule(cur_task, false);
- xizi_task_manager.task_block(&xizi_task_manager.task_blocked_list_head, cur_task);
- }
- }
+ // end of userland copy
+ if (cur_userland_idx < arr_capacity) {
+ userland_session_arr[cur_userland_idx].buf = NULL;
}
+ if (queue_is_empty(&cur_task->sessions_in_handle) && queue_is_empty(&cur_task->sessions_to_be_handle)) {
+ THREAD_TRANS_STATE(cur_task, BLOCKED);
+ }
return 0;
}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_as_server.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_as_server.c
index ee0dbce51..ff929b4ae 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_as_server.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_as_server.c
@@ -35,8 +35,6 @@ Modification:
#include "syscall.h"
#include "task.h"
-#define SERVER_DIR_NAME_SIZE 14
-
int sys_register_as_server(char* name)
{
// get server thread
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c
index 38a19bcff..601e6e755 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c
@@ -75,9 +75,8 @@ static void send_irq_to_user(int irq_num)
buf->header.done = 0;
buf->header.magic = IPC_MSG_MAGIC;
buf->header.valid = 1;
-
- if (irq_forward_table[irq_num].handle_task->state == BLOCKED) {
- xizi_task_manager.task_unblock(irq_forward_table[irq_num].handle_task);
+ if (enqueue(&irq_forward_table[irq_num].handle_task->sessions_to_be_handle, 0, (void*)&irq_forward_table[irq_num].p_kernel_session->server_side)) {
+ THREAD_TRANS_STATE(irq_forward_table[irq_num].handle_task, TRANS_WAKING);
}
/* add session head */
@@ -92,7 +91,7 @@ int user_irq_handler(int irq, void* tf, void* arg)
next_task_emergency = irq_forward_table[irq].handle_task;
if (cur_cpu()->task != NULL) {
- xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false);
+ THREAD_TRANS_STATE(cur_cpu()->task, READY);
}
}
return 0;
@@ -117,15 +116,18 @@ int sys_register_irq(int irq_num, int irq_opcode)
// init kerenl sender proxy
if (kernel_irq_proxy == NULL) {
/// @todo handle corner cases
- struct MemSpace* pmemspace = alloc_memspace();
+ struct MemSpace* pmemspace = alloc_memspace("KernelIrqProxy");
if (pmemspace == NULL) {
return -1;
}
xizi_pager.new_pgdir(&pmemspace->pgdir);
memcpy(pmemspace->pgdir.pd_addr, kern_pgdir.pd_addr, TOPLEVLE_PAGEDIR_SIZE);
- kernel_irq_proxy = xizi_task_manager.new_task_cb(pmemspace);
- kernel_irq_proxy->state = NEVER_RUN;
+ struct TaskLifecycleOperations* tlo = GetSysObject(struct TaskLifecycleOperations, &xizi_task_manager.task_lifecycle_ops_tag);
+ kernel_irq_proxy = tlo->new_thread(pmemspace);
+ task_trans_sched_state(&kernel_irq_proxy->snode, //
+ &g_scheduler.snode_state_pool[INIT], //
+ &g_scheduler.snode_state_pool[NEVER_RUN], NEVER_RUN);
}
// bind irq to session
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_semaphore.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_semaphore.c
index 18c0fd7e7..0aff31d7c 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_semaphore.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_semaphore.c
@@ -22,7 +22,7 @@
#include "syscall.h"
#include "task.h"
-extern bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, uint32_t sem_id);
+extern bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, sem_id_t sem_id);
int sys_semaphore(sys_sem_option op, int param)
{
bool ret = false;
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_sleep.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_sleep.c
new file mode 100644
index 000000000..d792b0520
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_sleep.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020 AIIT XUOS Lab
+ * XiUOS is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+/**
+ * @file sys_sleep.c
+ * @brief task sleep
+ * @version 3.0
+ * @author AIIT XUOS Lab
+ * @date 2023.08.25
+ */
+
+/*************************************************
+File name: sys_sleep.c
+Description:
+Others:
+History:
+1. Date: 2023-08-28
+Author: AIIT XUOS Lab
+Modification:
+1. first version
+*************************************************/
+#include "multicores.h"
+#include "syscall.h"
+#include "task.h"
+
+#include "assert.h"
+
+int sys_sleep(intptr_t ms)
+{
+ struct Thread* cur_task = cur_cpu()->task;
+ cur_task->snode.sleep_context.remain_ms = ms;
+ THREAD_TRANS_STATE(cur_task, SLEEPING);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c
index fa5994a01..3b4f1ad86 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c
@@ -38,7 +38,7 @@ extern int sys_new_thread(struct MemSpace* pmemspace, struct Thread* task, uintp
int sys_spawn(char* img_start, char* name, char** argv)
{
// alloc a new memspace
- struct MemSpace* pmemspace = alloc_memspace();
+ struct MemSpace* pmemspace = alloc_memspace(name);
if (pmemspace == NULL) {
return -1;
}
@@ -52,10 +52,16 @@ int sys_spawn(char* img_start, char* name, char** argv)
}
// alloc a new pcb
- struct Thread* new_task_cb = xizi_task_manager.new_task_cb(pmemspace);
+ struct TaskLifecycleOperations* tlo = GetSysObject(struct TaskLifecycleOperations, &xizi_task_manager.task_lifecycle_ops_tag);
+ struct Thread* new_task_cb = tlo->new_thread(pmemspace);
if (UNLIKELY(!new_task_cb)) {
- ERROR("Unable to new task control block.\n");
- free_memspace(pmemspace);
+ ERROR("Unable to new task control block %x.\n");
+ // error task allocation may free memspace before hand
+ // @todo use task ref map to handle this scene
+ if (NULL != pmemspace->tag.meta) {
+ free_memspace(pmemspace);
+ }
+
return -1;
}
assert(!IS_DOUBLE_LIST_EMPTY(&pmemspace->thread_list_guard));
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c
index 502fde0e4..5d959986d 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c
@@ -30,6 +30,7 @@ Modification:
#include
#include
+#include "actracer.h"
#include "assert.h"
#include "buddy.h"
#include "log.h"
@@ -41,65 +42,50 @@ Modification:
extern uint8_t _binary_fs_img_start[], _binary_fs_img_end[];
#define SHOWINFO_BORDER_LINE() LOG_PRINTF("******************************************************\n");
-#define SHOWTASK_TASK_BASE_INFO(task) LOG_PRINTF(" %-6d %-16s %-4d 0x%x(%-d)\n", task->tid, task->name, task->priority, task->memspace->mem_size >> 10, task->memspace->mem_size >> 10)
+#define SHOWTASK_TASK_BASE_INFO(task) LOG_PRINTF(" %-6d %-16s %-4d 0x%x(%-d)\n", task->tid, task->name, 0, task->memspace->mem_size >> 10, task->memspace->mem_size >> 10)
+
+bool print_info(RbtNode* node, void* data)
+{
+ struct ScheduleNode* snode = (struct ScheduleNode*)node->data;
+ struct Thread* thd = snode->pthd;
+ switch (snode->state) {
+ case INIT:
+ LOG_PRINTF("%-8s", "INIT");
+ break;
+ case READY:
+ LOG_PRINTF("%-8s", "READY");
+ break;
+ case RUNNING:
+ LOG_PRINTF("%-8s", "RUNNING");
+ break;
+ case DEAD:
+ LOG_PRINTF("%-8s", "DEAD");
+ break;
+ case BLOCKED:
+ LOG_PRINTF("%-8s", "BLOCK");
+ break;
+ case SLEEPING:
+ LOG_PRINTF("%-8s", "SLEEP");
+ break;
+ default:
+ break;
+ }
+
+ SHOWTASK_TASK_BASE_INFO(thd);
+ return true;
+}
void show_tasks(void)
{
- struct Thread* task = NULL;
SHOWINFO_BORDER_LINE();
for (int i = 0; i < NR_CPU; i++) {
LOG_PRINTF("CPU %-2d: %s\n", i, (global_cpus[i].task == NULL ? "NULL" : global_cpus[i].task->name));
}
SHOWINFO_BORDER_LINE();
LOG_PRINTF("%-8s %-6s %-16s %-4s %-8s\n", "STAT", "ID", "TASK", "PRI", "MEM(KB)");
- DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_running_list_head, node)
- {
- LOG_PRINTF("%-8s", "RUNNING");
- SHOWTASK_TASK_BASE_INFO(task);
- }
- for (int i = 0; i < TASK_MAX_PRIORITY; i++) {
- if (IS_DOUBLE_LIST_EMPTY(&xizi_task_manager.task_list_head[i])) {
- continue;
- }
- DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[i], node)
- {
- switch (task->state) {
- case INIT:
- LOG_PRINTF("%-8s", "INIT");
- break;
- case READY:
- LOG_PRINTF("%-8s", "READY");
- break;
- case RUNNING:
- LOG_PRINTF("%-8s", "RUNNING");
- break;
- case DEAD:
- LOG_PRINTF("%-8s", "DEAD");
- break;
- default:
- break;
- }
-
- SHOWTASK_TASK_BASE_INFO(task);
- }
- }
-
- DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_blocked_list_head, node)
- {
- LOG_PRINTF("%-8s", "BLOCK");
- SHOWTASK_TASK_BASE_INFO(task);
- }
-
- struct ksemaphore* sem = NULL;
- DOUBLE_LIST_FOR_EACH_ENTRY(sem, &xizi_task_manager.semaphore_pool.sem_list_guard, sem_list_node)
- {
- task = NULL;
- DOUBLE_LIST_FOR_EACH_ENTRY(task, &sem->wait_list_guard, node)
- {
- LOG_PRINTF("%-8s", "BLOCK");
- SHOWTASK_TASK_BASE_INFO(task);
- }
+ for (int pool_id = INIT; pool_id < NR_STATE; pool_id++) {
+ rbt_traverse(&g_scheduler.snode_state_pool[pool_id], print_info, NULL);
}
SHOWINFO_BORDER_LINE();
@@ -147,7 +133,7 @@ void show_cpu(void)
assert(current_task != NULL);
LOG_PRINTF(" ID COMMAND USED_TICKS FREE_TICKS \n");
- LOG_PRINTF(" %d %s %d %d\n", cpu_id, current_task->name, TASK_CLOCK_TICK - current_task->remain_tick, current_task->remain_tick);
+ LOG_PRINTF(" %d %s %d %d\n", cpu_id, current_task->name, TASK_CLOCK_TICK - current_task->snode.sched_context.remain_tick, current_task->snode.sched_context.remain_tick);
LOG_PRINTF("***********************************************************\n");
return;
@@ -190,6 +176,10 @@ int sys_state(sys_state_option option, sys_state_info* info)
hw_current_second(&info->current_second);
break;
}
+ case SYS_STATE_SHOW_ACTREE: {
+ debug_list_tracetree();
+ break;
+ }
case SYS_STATE_TEST:
default:
break;
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_thread.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_thread.c
index 7560f8afa..aadef737b 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_thread.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_thread.c
@@ -40,8 +40,9 @@ int sys_new_thread(struct MemSpace* pmemspace, struct Thread* task, uintptr_t en
struct ThreadStackPointer loaded_sp = load_user_stack(pmemspace, argv);
if (loaded_sp.stack_idx == -1) {
ERROR("Uable to load params to memspace.\n");
- /* memspace is freed alone with free_pcb() */
- xizi_task_manager.free_pcb(task);
+ /* memspace is freed alone with free_thread() */
+ struct TaskLifecycleOperations* tlo = GetSysObject(struct TaskLifecycleOperations, &xizi_task_manager.task_lifecycle_ops_tag);
+ tlo->free_thread(task);
return -1;
}
@@ -64,10 +65,10 @@ int sys_new_thread(struct MemSpace* pmemspace, struct Thread* task, uintptr_t en
last = name + 1;
}
}
- strncpy(task->name, last, sizeof(task->name));
+ strncpy(task->name, last, sizeof(task->name) - 1);
// init pcb schedule attributes
- xizi_task_manager.task_set_default_schedule_attr(task);
+ task_into_ready(task);
// thread init done by here
if (pmemspace->thread_to_notify == NULL) {
@@ -84,7 +85,8 @@ int sys_thread(uintptr_t entry, char* name, char** argv)
// use current task's memspace
struct MemSpace* pmemspace = cur_task->memspace;
- struct Thread* task = xizi_task_manager.new_task_cb(pmemspace);
+ struct TaskLifecycleOperations* tlo = GetSysObject(struct TaskLifecycleOperations, &xizi_task_manager.task_lifecycle_ops_tag);
+ struct Thread* task = tlo->new_thread(pmemspace);
if (UNLIKELY(!task)) {
ERROR("Unable to new task control block.\n");
return -1;
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_wait_session.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_wait_session.c
new file mode 100644
index 000000000..2393a94da
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_wait_session.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2020 AIIT XUOS Lab
+ * XiUOS is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+/**
+ * @file sys_wait_session.c
+ * @brief
+ * @version 3.0
+ * @author AIIT XUOS Lab
+ * @date 2023.08.25
+ */
+
+/*************************************************
+File name: sys_poll_session.c
+Description: server poll its connected sessions
+Others:
+History:
+1. Date: 2023-08-28
+Author: AIIT XUOS Lab
+Modification:
+1. first version
+*************************************************/
+#include "multicores.h"
+#include "share_page.h"
+
+#include "syscall.h"
+
+extern bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, sem_id_t sem_id);
+int sys_wait_session(struct Session* userland_session)
+{
+ struct Thread* cur_task = cur_cpu()->task;
+
+ RbtNode* client_session_node = rbt_search(&cur_task->cli_sess_map, userland_session->id);
+ if (client_session_node == NULL) {
+ ERROR("Error waiting session from %s: Invalid session %d\n", cur_task->name, userland_session->id);
+ return -1;
+ }
+
+ struct client_session* client_session = (struct client_session*)client_session_node->data;
+ if (CLIENT_SESSION_BACKEND(client_session)->session_id != userland_session->id || //
+ client_session->buf_addr != (uintptr_t)userland_session->buf) {
+ ERROR("Error waiting session from %s: Invalid session %d\n", cur_task->name, userland_session->id);
+ return -1;
+ }
+
+ /* handle calling */
+ struct session_backend* session_backend = CLIENT_SESSION_BACKEND(client_session);
+ struct Thread* server_to_call = session_backend->server;
+ if (!enqueue(&server_to_call->sessions_to_be_handle, 0, (void*)&session_backend->server_side)) {
+ sys_exit(cur_task);
+ return -1;
+ }
+ assert(!queue_is_empty(&server_to_call->sessions_to_be_handle));
+
+ ksemaphore_wait(&xizi_task_manager.semaphore_pool, cur_task, session_backend->client_sem_to_wait);
+ THREAD_TRANS_STATE(server_to_call, TRANS_WAKING);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c
index 45c3f468f..e9f20afcc 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c
@@ -36,28 +36,6 @@ Modification:
int sys_yield(task_yield_reason reason)
{
struct Thread* cur_task = cur_cpu()->task;
- xizi_task_manager.task_yield_noschedule(cur_task, false);
-
- // handle ipc block
- if ((reason & SYS_TASK_YIELD_BLOCK_IPC) != 0) {
- if (cur_task->advance_unblock) {
- cur_task->advance_unblock = false;
- return 0;
- } else {
- xizi_task_manager.task_block(&xizi_task_manager.task_blocked_list_head, cur_task);
- }
-
- // wake up all possible server
- struct client_session* client_session = NULL;
- DOUBLE_LIST_FOR_EACH_ENTRY(client_session, &cur_task->cli_sess_listhead, node)
- {
- assert(client_session != NULL);
- struct session_backend* session_backend = CLIENT_SESSION_BACKEND(client_session);
- if (session_backend->server->state == BLOCKED) {
- xizi_task_manager.task_unblock(session_backend->server);
- }
- }
- }
-
+ THREAD_TRANS_STATE(cur_task, READY);
return 0;
}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c
index d3ae51f67..76135f24c 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c
@@ -69,7 +69,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
ret = sys_state(param1, (sys_state_info*)param2);
break;
case SYSCALL_MMAP:
- ret = sys_mmap((uintptr_t*)param1, (uintptr_t*)param2, (int)param3, (int)param4);
+ ret = sys_mmap_v2((uintptr_t*)param1, (uintptr_t*)param2, (int)param3, (sys_mmap_info*)param4);
break;
case SYSCALL_REGISTER_IRQ:
ret = sys_register_irq((int)param1, (int)param2);
@@ -80,6 +80,12 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
case SYSCALL_SEMAPHORE:
ret = sys_semaphore((sys_sem_option)param1, (int)param2);
break;
+ case SYSCALL_SLEEP:
+ ret = sys_sleep((intptr_t)param1);
+ break;
+ case SYSCALL_WAIT_SESSION:
+ ret = sys_wait_session((struct Session*)param1);
+ break;
default:
ERROR("Unsurport syscall(%d) right now\n", sys_num);
ret = -1;
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/memspace.c b/Ubiquitous/XiZi_AIoT/softkernel/task/memspace.c
index 8c906d1bd..cb11858a9 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/task/memspace.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/task/memspace.c
@@ -41,7 +41,7 @@ Modification:
#define MAX_SUPPORT_PARAMS 32
-struct MemSpace* alloc_memspace()
+struct MemSpace* alloc_memspace(char* name)
{
struct MemSpace* pmemspace = slab_alloc(&xizi_task_manager.memspace_allocator);
if (pmemspace == NULL) {
@@ -56,28 +56,51 @@ struct MemSpace* alloc_memspace()
pmemspace->mem_size = 0;
pmemspace->pgdir.pd_addr = 0;
pmemspace->thread_to_notify = NULL;
- CreateResourceTag(&pmemspace->tag, &xizi_task_manager.tag, NULL, TRACER_OWNER, (void*)pmemspace);
+ if (!CreateResourceTag(&pmemspace->tag, &xizi_task_manager.tag, name, TRACER_OWNER, (void*)pmemspace)) {
+ DEBUG("Register MemSpace %s failed\n", name);
+ slab_free(&xizi_task_manager.memspace_allocator, (void*)pmemspace);
+ return NULL;
+ }
+ assert(pmemspace->tag.meta != NULL);
+
+ if (!CreateResourceTag(&pmemspace->kernspace_mem_usage.tag, &pmemspace->tag, "MemUsage", TRACER_SYSOBJECT, (void*)&pmemspace->kernspace_mem_usage) || //
+ !CreateResourceTag(&pmemspace->userspace_mem_usage.tag, &pmemspace->tag, "UserMemUsage", TRACER_SYSOBJECT, (void*)&pmemspace->userspace_mem_usage) || //
+ !CreateResourceTag(&pmemspace->customized_mapping_mem_map.tag, &pmemspace->tag, "CustomizaedMemMapping", TRACER_SYSOBJECT, (void*)&pmemspace->customized_mapping_mem_map)) {
+ DEBUG("Register MemUsage %s failed\n", name);
+ slab_free(&xizi_task_manager.memspace_allocator, (void*)pmemspace);
+ DeleteResource(&pmemspace->tag, &xizi_task_manager.tag);
+ return NULL;
+ }
+
+ rbtree_init(&pmemspace->kernspace_mem_usage.mem_block_map);
+ rbtree_init(&pmemspace->userspace_mem_usage.mem_block_map);
+ rbtree_init(&pmemspace->customized_mapping_mem_map.mem_block_map);
return pmemspace;
}
void free_memspace(struct MemSpace* pmemspace)
{
assert(pmemspace != NULL);
+ assert(IS_DOUBLE_LIST_EMPTY(&pmemspace->thread_list_guard));
/* free page table and all its allocated memories */
if (pmemspace->pgdir.pd_addr != NULL) {
xizi_pager.free_user_pgdir(&pmemspace->pgdir);
}
- TracerNode* tmp_node = NULL;
- DOUBLE_LIST_FOR_EACH_ENTRY(tmp_node, &pmemspace->tag.meta->children_guard, list_node)
- {
- assert((uintptr_t)tmp_node->p_resource >= PHY_MEM_BASE && (uintptr_t)tmp_node->p_resource < PHY_MEM_STOP);
- if ((uintptr_t)tmp_node->p_resource < PHY_USER_FREEMEM_BASE) {
- kfree(P2V(tmp_node->p_resource));
- } else {
- raw_free(tmp_node->p_resource);
- }
+ // delete space
+ RbtNode* rbt_node = pmemspace->kernspace_mem_usage.mem_block_map.root;
+ while (rbt_node != NULL) {
+ assert((uintptr_t)V2P(rbt_node->key) >= PHY_MEM_BASE && (uintptr_t)V2P(rbt_node->key) < PHY_MEM_STOP);
+ kfree_by_ownership(pmemspace->kernspace_mem_usage.tag, (void*)rbt_node->key);
+ rbt_node = pmemspace->kernspace_mem_usage.mem_block_map.root;
+ }
+
+ rbt_node = pmemspace->userspace_mem_usage.mem_block_map.root;
+ while (rbt_node != NULL) {
+ assert((uintptr_t)rbt_node->key >= PHY_MEM_BASE && (uintptr_t)rbt_node->key < PHY_MEM_STOP);
+ raw_free_by_ownership(pmemspace->userspace_mem_usage.tag, (void*)rbt_node->key);
+ rbt_node = pmemspace->userspace_mem_usage.mem_block_map.root;
}
/* free ipc virt address allocator */
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/schedule.c b/Ubiquitous/XiZi_AIoT/softkernel/task/schedule.c
index 9df773558..9907c3ce2 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/task/schedule.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/task/schedule.c
@@ -28,67 +28,132 @@ Modification:
1. first version
*************************************************/
#include "log.h"
-#include "scheduler.h"
+#include "multicores.h"
+#include "schedule_algo.h"
+
+static struct Thread* next_runable_task;
+static uint64_t min_run_time;
+#define MIN_RUN_TIME_BOUND 5
+
+bool find_runable_task(RbtNode* node, void* data)
+{
+ struct ScheduleNode* snode = (struct ScheduleNode*)node->data;
+ struct Thread* thd = snode->pthd;
+
+ if (!thd->dead) {
+ if (thd->snode.sched_context.run_time <= min_run_time) {
+ next_runable_task = thd;
+ min_run_time = thd->snode.sched_context.run_time;
+ thd->snode.sched_context.run_time++;
+ }
+
+ if (min_run_time <= MIN_RUN_TIME_BOUND) {
+ return false;
+ }
+ return true;
+ } else {
+ struct TaskLifecycleOperations* tlo = GetSysObject(struct TaskLifecycleOperations, &xizi_task_manager.task_lifecycle_ops_tag);
+ tlo->free_thread(thd);
+ return false;
+ }
+
+ return true;
+}
struct Thread* max_priority_runnable_task(void)
{
- static struct Thread* task = NULL;
- static int priority = 0;
-
- priority = __builtin_ffs(ready_task_priority) - 1;
- if (priority > 31 || priority < 0) {
- return NULL;
- }
-
- DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[priority], node)
- {
- assert(task != NULL);
- if (task->state == READY && !task->dead) {
- // found a runnable task, stop this look up
- return task;
- } else if (task->dead && task->state != RUNNING) {
- xizi_task_manager.free_pcb(task);
- return NULL;
- }
- }
- return NULL;
+ /// @todo better strategy
+ next_runable_task = NULL;
+ min_run_time = UINT64_MAX;
+ rbt_traverse(&g_scheduler.snode_state_pool[READY], find_runable_task, NULL);
+ return next_runable_task;
}
-struct Thread* round_robin_runnable_task(uint32_t priority)
+#include "multicores.h"
+#include "rbtree.h"
+#include "task.h"
+
+bool init_schedule_node(struct ScheduleNode* snode, struct Thread* bind_thd)
{
- struct Thread* task = NULL;
+ snode->pthd = bind_thd;
+ snode->snode_id = bind_thd->tid;
- DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[priority], node)
- {
- if (task->state == READY && !task->dead) {
- // found a runnable task, stop this look up
- return task;
- } else if (task->dead && task->state != RUNNING) {
- xizi_task_manager.free_pcb(task);
- return NULL;
- }
+ snode->sched_context.remain_tick = 0;
+ snode->sched_context.run_time = 0;
+
+ snode->sleep_context.remain_ms = 0;
+ snode->state = INIT;
+ if (RBTTREE_INSERT_SECC != rbt_insert(&g_scheduler.snode_state_pool[INIT], //
+ snode->snode_id, (void*)snode)) {
+ return false;
}
-
- return NULL;
+ queue_init(&snode->state_trans_signal_queue);
+ return true;
}
-/* recover task priority */
-void recover_priority(void)
+void enqueue_task_trans_state(struct Thread* thd, enum ThreadState state)
{
- struct Thread* task = NULL;
- for (int i = 1; i < TASK_MAX_PRIORITY; i++) {
- if (i == TASK_DEFAULT_PRIORITY)
- continue;
- DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[i], node)
- {
- if (!IS_DOUBLE_LIST_EMPTY(&task->node)) {
- // DEBUG("%s priority recover\n", task->name);
- task->priority = TASK_DEFAULT_PRIORITY;
- doubleListDel(&task->node);
- doubleListAddOnBack(&task->node, &xizi_task_manager.task_list_head[task->priority]);
- i--;
- break;
- }
- }
+ /// @todo (current bug) handle memory drain
+ assert(enqueue(&thd->snode.state_trans_signal_queue, state, NULL));
+ int res = rbt_insert(&g_scheduler.state_trans_ref_map, thd->tid, (void*)thd);
+ assert(RBTTREE_INSERT_SECC == res || RBTTREE_INSERT_EXISTED == res);
+}
+
+bool task_trans_sched_state(struct ScheduleNode* snode, RbtTree* from_pool, RbtTree* to_pool, enum ThreadState target_state)
+{
+ assert(snode != NULL);
+ assert(snode->snode_id != UNINIT_SNODE_ID && snode->pthd != NULL);
+ if (RBTTREE_DELETE_SUCC != rbt_delete(from_pool, snode->snode_id)) {
+ DEBUG("Thread %d not in from schedule pool\n", snode->pthd->tid);
+ return false;
}
+
+ if (RBTTREE_INSERT_SECC != rbt_insert(to_pool, snode->snode_id, (void*)snode)) {
+ DEBUG("Thread %d trans state failed\n", snode->pthd->tid);
+ return false;
+ }
+
+ snode->state = target_state;
+ return true;
+}
+
+void task_dead(struct Thread* thd)
+{
+ assert(thd != NULL);
+ struct ScheduleNode* snode = &thd->snode;
+
+ assert(snode->state == INIT || snode->state == READY);
+ bool trans_res = task_trans_sched_state(snode, //
+ &g_scheduler.snode_state_pool[snode->state], //
+ &g_scheduler.snode_state_pool[DEAD], DEAD);
+ assert(trans_res = true);
+ assert(RBTTREE_DELETE_SUCC == rbt_delete(&g_scheduler.snode_state_pool[DEAD], snode->snode_id));
+ return;
+}
+
+void task_block(struct Thread* thd)
+{
+ assert(thd != NULL);
+ struct ScheduleNode* snode = &thd->snode;
+ enum ThreadState thd_cur_state = snode->state;
+
+ bool trans_res = task_trans_sched_state(snode, //
+ &g_scheduler.snode_state_pool[thd_cur_state], //
+ &g_scheduler.snode_state_pool[BLOCKED], BLOCKED);
+ assert(trans_res = true);
+ return;
+}
+
+void task_into_ready(struct Thread* thd)
+{
+ assert(thd != NULL);
+ struct ScheduleNode* snode = &thd->snode;
+ enum ThreadState thd_cur_state = snode->state;
+
+ bool trans_res = task_trans_sched_state(snode, //
+ &g_scheduler.snode_state_pool[thd_cur_state], //
+ &g_scheduler.snode_state_pool[READY], READY);
+ snode->sched_context.remain_tick = TASK_CLOCK_TICK;
+ assert(trans_res = true);
+ return;
}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/semaphore.c b/Ubiquitous/XiZi_AIoT/softkernel/task/semaphore.c
index f1c5b5443..fd3589f54 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/task/semaphore.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/task/semaphore.c
@@ -24,29 +24,28 @@
void semaphore_pool_init(struct XiziSemaphorePool* sem_pool)
{
assert(sem_pool != NULL);
- sem_pool->next_sem_id = 1;
- slab_init(&sem_pool->allocator, sizeof(struct ksemaphore));
+ sem_pool->next_sem_id = INVALID_SEM_ID + 1;
+ slab_init(&sem_pool->allocator, sizeof(struct ksemaphore), "SemAllocator");
doubleListNodeInit(&sem_pool->sem_list_guard);
+ rbtree_init(&sem_pool->sem_pool_map);
+ sem_pool->nr_sem = 0;
}
-static inline struct ksemaphore* ksemaphore_get_by_id(struct XiziSemaphorePool* sem_pool, int sem_id)
+static inline struct ksemaphore* ksemaphore_get_by_id(struct XiziSemaphorePool* sem_pool, sem_id_t sem_id)
{
- struct ksemaphore* sem = NULL;
- DOUBLE_LIST_FOR_EACH_ENTRY(sem, &sem_pool->sem_list_guard, sem_list_node)
- {
- if (sem->id == sem_id) {
- return sem;
- }
+ RbtNode* target_sem_node = rbt_search(&sem_pool->sem_pool_map, sem_id);
+ if (target_sem_node == NULL) {
+ return NULL;
}
- return NULL;
+ return (struct ksemaphore*)target_sem_node->data;
}
-int ksemaphore_alloc(struct XiziSemaphorePool* sem_pool, int val)
+sem_id_t ksemaphore_alloc(struct XiziSemaphorePool* sem_pool, sem_val_t val)
{
struct ksemaphore* sem = (struct ksemaphore*)slab_alloc(&sem_pool->allocator);
if (sem == NULL) {
ERROR("No memeory to alloc new semaphore.\n");
- return -1;
+ return INVALID_SEM_ID;
}
/* No error down here */
@@ -55,28 +54,48 @@ int ksemaphore_alloc(struct XiziSemaphorePool* sem_pool, int val)
sem->id = sem_pool->next_sem_id++;
if (UNLIKELY(sem->id == 0)) {
slab_free(&sem_pool->allocator, sem);
- return -1;
+ return INVALID_SEM_ID;
}
sem->val = val;
doubleListNodeInit(&sem->sem_list_node);
- doubleListNodeInit(&sem->wait_list_guard);
+ rbtree_init(&sem->wait_thd_tree);
+
+ if (0 != rbt_insert(&sem_pool->sem_pool_map, sem->id, sem)) {
+ slab_free(&sem_pool->allocator, sem);
+ return INVALID_SEM_ID;
+ }
- /* list sem to sem_pool */
doubleListAddOnHead(&sem->sem_list_node, &sem_pool->sem_list_guard);
+ sem_pool->nr_sem++;
return sem->id;
}
-bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, uint32_t sem_id)
+bool ksemaphore_consume(struct XiziSemaphorePool* sem_pool, sem_id_t sem_id, sem_val_t decre)
+{
+ struct ksemaphore* sem = ksemaphore_get_by_id(sem_pool, sem_id);
+ // invalid sem id
+ if (sem == NULL) {
+ return false;
+ }
+
+ // if (decre >= 0) {
+ sem->val -= decre;
+ // }
+ return true;
+}
+
+bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, sem_id_t sem_id)
{
assert(thd != NULL);
- assert(thd->state == RUNNING);
+ assert(thd->snode.state == RUNNING);
/* find sem */
struct ksemaphore* sem = ksemaphore_get_by_id(sem_pool, sem_id);
// invalid sem id
if (sem == NULL) {
return false;
}
+ // DEBUG("%s waiting sem %lu(%d), nr_sem: %d I\n", thd->name, sem_id, sem->val, sem_pool->nr_sem);
// no need to wait
if (sem->val > 0) {
@@ -86,12 +105,13 @@ bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, uin
// waiting at the sem
sem->val--;
- xizi_task_manager.task_yield_noschedule(thd, false);
- xizi_task_manager.task_block(&sem->wait_list_guard, thd);
+ THREAD_TRANS_STATE(thd, BLOCKED);
+ int rbt_insert_res = rbt_insert(&sem->wait_thd_tree, thd->tid, thd);
+ assert(RBTTREE_INSERT_SECC == rbt_insert_res || RBTTREE_INSERT_EXISTED == rbt_insert_res);
return true;
}
-bool ksemaphore_signal(struct XiziSemaphorePool* sem_pool, uint32_t sem_id)
+bool ksemaphore_signal(struct XiziSemaphorePool* sem_pool, sem_id_t sem_id)
{
/* find sem */
struct ksemaphore* sem = ksemaphore_get_by_id(sem_pool, sem_id);
@@ -100,19 +120,19 @@ bool ksemaphore_signal(struct XiziSemaphorePool* sem_pool, uint32_t sem_id)
return false;
}
- if (sem->val < 0) {
- if (!IS_DOUBLE_LIST_EMPTY(&sem->wait_list_guard)) {
- struct Thread* thd = CONTAINER_OF(sem->wait_list_guard.next, struct Thread, node);
- assert(thd != NULL && thd->state == BLOCKED);
- xizi_task_manager.task_unblock(thd);
- }
+ if (sem->val < 0 && !rbt_is_empty(&sem->wait_thd_tree)) {
+ assert(!rbt_is_empty(&sem->wait_thd_tree));
+ RbtNode* root = sem->wait_thd_tree.root;
+ struct Thread* thd = (struct Thread*)root->data;
+ rbt_delete(&sem->wait_thd_tree, root->key);
+ THREAD_TRANS_STATE(thd, TRANS_WAKING);
}
sem->val++;
return true;
}
-bool ksemaphore_free(struct XiziSemaphorePool* sem_pool, uint32_t sem_id)
+bool ksemaphore_signal_no_wake(struct XiziSemaphorePool* sem_pool, sem_id_t sem_id)
{
/* find sem */
struct ksemaphore* sem = ksemaphore_get_by_id(sem_pool, sem_id);
@@ -121,15 +141,25 @@ bool ksemaphore_free(struct XiziSemaphorePool* sem_pool, uint32_t sem_id)
return false;
}
- struct Thread* thd = NULL;
- DOUBLE_LIST_FOR_EACH_ENTRY(thd, &sem->wait_list_guard, node)
- {
- assert(thd != NULL);
- xizi_task_manager.task_unblock(thd);
+ sem->val++;
+ return true;
+}
+
+bool ksemaphore_free(struct XiziSemaphorePool* sem_pool, sem_id_t sem_id)
+{
+ /* find sem */
+ struct ksemaphore* sem = ksemaphore_get_by_id(sem_pool, sem_id);
+ // invalid sem id
+ if (sem == NULL) {
+ return false;
}
+ // by design: no waking any waiting threads
+
+ rbt_delete(&sem_pool->sem_pool_map, sem_id);
doubleListDel(&sem->sem_list_node);
slab_free(&sem_pool->allocator, sem);
+ sem_pool->nr_sem--;
return true;
}
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c
index 6567dc599..d770d19d4 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c
@@ -35,105 +35,97 @@ Modification:
#include "kalloc.h"
#include "memspace.h"
#include "multicores.h"
-#include "scheduler.h"
+#include "schedule_algo.h"
#include "syscall.h"
#include "task.h"
+#include "trap_common.h"
struct CPU global_cpus[NR_CPU];
uint32_t ready_task_priority;
-static inline void task_node_leave_list(struct Thread* task)
-{
- doubleListDel(&task->node);
- if (IS_DOUBLE_LIST_EMPTY(&xizi_task_manager.task_list_head[task->priority])) {
- ready_task_priority &= ~((uint32_t)1 << task->priority);
- }
-}
-
-static inline void task_node_add_to_ready_list_head(struct Thread* task)
-{
- doubleListAddOnHead(&task->node, &xizi_task_manager.task_list_head[task->priority]);
- ready_task_priority |= ((uint32_t)1 << task->priority);
-}
-
-static inline void task_node_add_to_ready_list_back(struct Thread* task)
-{
- doubleListAddOnBack(&task->node, &xizi_task_manager.task_list_head[task->priority]);
- ready_task_priority |= ((uint32_t)1 << task->priority);
-}
+struct GlobalTaskPool global_task_pool;
+struct Scheduler g_scheduler;
+extern struct TaskLifecycleOperations task_lifecycle_ops;
static void _task_manager_init()
{
+ assert(CreateResourceTag(&xizi_task_manager.task_lifecycle_ops_tag, &xizi_task_manager.tag, //
+ "TaskLifeCycleOpTool", TRACER_SYSOBJECT, (void*)&task_lifecycle_ops));
+
// init task list to NULL
for (int i = 0; i < TASK_MAX_PRIORITY; i++) {
doubleListNodeInit(&xizi_task_manager.task_list_head[i]);
}
+
+ /* task scheduling list */
doubleListNodeInit(&xizi_task_manager.task_blocked_list_head);
doubleListNodeInit(&xizi_task_manager.task_running_list_head);
+ doubleListNodeInit(&xizi_task_manager.task_sleep_list_head);
+
// init task (slab) allocator
- slab_init(&xizi_task_manager.memspace_allocator, sizeof(struct MemSpace));
- slab_init(&xizi_task_manager.task_allocator, sizeof(struct Thread));
- slab_init(&xizi_task_manager.task_buddy_allocator, sizeof(struct KBuddy));
+ slab_init(&xizi_task_manager.memspace_allocator, sizeof(struct MemSpace), "MemlpaceCtrlBlockAllocator");
+ slab_init(&xizi_task_manager.task_allocator, sizeof(struct Thread), "TreadCtrlBlockAllocator");
+ slab_init(&xizi_task_manager.task_buddy_allocator, sizeof(struct KBuddy), "DMBuddyAllocator");
+
+ /* global semaphore factory */
semaphore_pool_init(&xizi_task_manager.semaphore_pool);
+ /* task pool */
+ doubleListNodeInit(&global_task_pool.thd_listing_head);
+ rbtree_init(&global_task_pool.thd_ref_map);
+
+ // scheduler
+ assert(CreateResourceTag(&g_scheduler.tag, &xizi_task_manager.tag, //
+ "GlobalScheduler", TRACER_SYSOBJECT, (void*)&g_scheduler));
+ semaphore_pool_init(&g_scheduler.semaphore_pool);
+ for (int pool_id = 0; pool_id < NR_STATE; pool_id++) {
+ rbtree_init(&g_scheduler.snode_state_pool[pool_id]);
+ }
+ rbtree_init(&g_scheduler.state_trans_ref_map);
+
// tid pool
- xizi_task_manager.next_pid = 0;
+ xizi_task_manager.next_pid = 1;
// init priority bit map
ready_task_priority = 0;
}
-/// @brief alloc a new task without init
-static struct Thread* _alloc_task_cb()
-{
- // alloc task and add it to used task list
- struct Thread* task = (struct Thread*)slab_alloc(&xizi_task_manager.task_allocator);
- if (UNLIKELY(task == NULL)) {
- ERROR("Not enough memory\n");
- return NULL;
- }
- // set tid once task is allocated
- memset(task, 0, sizeof(*task));
- task->tid = xizi_task_manager.next_pid++;
- task->thread_context.user_stack_idx = -1;
-
- return task;
-}
-
int _task_return_sys_resources(struct Thread* ptask)
{
assert(ptask != NULL);
/* handle sessions for condition 1, ref. delete_share_pages() */
- struct session_backend* session_backend = NULL;
// close all server_sessions
- struct server_session* server_session = NULL;
while (!IS_DOUBLE_LIST_EMPTY(&ptask->svr_sess_listhead)) {
- server_session = CONTAINER_OF(ptask->svr_sess_listhead.next, struct server_session, node);
- assert(server_session != NULL);
- session_backend = SERVER_SESSION_BACKEND(server_session);
- assert(session_backend->server == ptask);
- // cut the connection from task to session
- server_session->closed = true;
- xizi_share_page_manager.delete_share_pages(session_backend);
- }
- // close all client_sessions
- struct client_session* client_session = NULL;
- while (!IS_DOUBLE_LIST_EMPTY(&ptask->cli_sess_listhead)) {
- client_session = CONTAINER_OF(ptask->cli_sess_listhead.next, struct client_session, node);
- assert(client_session != NULL);
- session_backend = CLIENT_SESSION_BACKEND(client_session);
- assert(session_backend->client == ptask);
- // cut the connection from task to session
- client_session->closed = true;
- xizi_share_page_manager.delete_share_pages(session_backend);
+ // RbtNode* sess_ref_node = ptask->svr_sess_map.root;
+ struct server_session* svr_session = CONTAINER_OF(ptask->svr_sess_listhead.next, struct server_session, node);
+ server_close_session(ptask, svr_session);
}
+ // close all client_sessions
+ while (!IS_DOUBLE_LIST_EMPTY(&ptask->cli_sess_listhead)) {
+ // RbtNode* sess_ref_node = ptask->cli_sess_map.root;
+ struct client_session* cli_session = CONTAINER_OF(ptask->cli_sess_listhead.next, struct client_session, node);
+ client_close_session(ptask, cli_session);
+
+ // info server that session is closed
+ struct session_backend* session_backend = CLIENT_SESSION_BACKEND(cli_session);
+ struct Thread* server_to_info = session_backend->server;
+ if (!enqueue(&server_to_info->sessions_to_be_handle, 0, (void*)&session_backend->server_side)) {
+ // @todo fix memory leak
+ } else {
+ assert(!queue_is_empty(&server_to_info->sessions_to_be_handle));
+ THREAD_TRANS_STATE(server_to_info, BLOCKED);
+ }
+ }
+
+ /* delete server identifier */
if (ptask->server_identifier.meta != NULL) {
+ // @todo figure out server-identifier ownership
struct TraceTag server_identifier_owner;
AchieveResourceTag(&server_identifier_owner, RequireRootTag(), "softkernel/server-identifier");
assert(server_identifier_owner.meta != NULL);
- DeleteResource(&ptask->server_identifier, &server_identifier_owner);
+ assert(DeleteResource(&ptask->server_identifier, &server_identifier_owner));
}
// delete registered irq if there is one
@@ -144,9 +136,18 @@ int _task_return_sys_resources(struct Thread* ptask)
return 0;
}
+#ifndef __riscv
+extern void trap_return(void);
+__attribute__((optimize("O0"))) void task_prepare_enter()
+{
+ xizi_leave_kernel();
+ trap_return();
+}
+#endif
+
/// @brief this function changes task list without locking, so it must be called inside a lock critical area
/// @param task
-static void _dealloc_task_cb(struct Thread* task)
+static void _free_thread(struct Thread* task)
{
if (UNLIKELY(task == NULL)) {
ERROR("deallocating a NULL task\n");
@@ -172,18 +173,21 @@ static void _dealloc_task_cb(struct Thread* task)
}
}
- /* free thread's kernel stack */
- if (task->thread_context.kern_stack_addr) {
- kfree((char*)task->thread_context.kern_stack_addr);
- }
+ // remove thread from used task list
+ task_dead(task);
/* free memspace if needed to */
if (task->memspace != NULL) {
+ /* free thread's kernel stack */
+ if (task->thread_context.kern_stack_addr) {
+ // kfree_by_ownership(task->memspace->kernspace_mem_usage.tag, (char*)task->thread_context.kern_stack_addr);
+ }
+
// awake deamon in this memspace
if (task->memspace->thread_to_notify != NULL) {
if (task->memspace->thread_to_notify != task) {
- if (task->memspace->thread_to_notify->state == BLOCKED) {
- xizi_task_manager.task_unblock(task->memspace->thread_to_notify);
+ if (task->memspace->thread_to_notify->snode.state == BLOCKED) {
+ THREAD_TRANS_STATE(task->memspace->thread_to_notify, TRANS_WAKING);
} else {
task->memspace->thread_to_notify->advance_unblock = true;
}
@@ -193,6 +197,7 @@ static void _dealloc_task_cb(struct Thread* task)
}
doubleListDel(&task->memspace_list_node);
+
/* free memspace if thread is the last one using it */
if (IS_DOUBLE_LIST_EMPTY(&task->memspace->thread_list_guard)) {
// free memspace
@@ -200,92 +205,170 @@ static void _dealloc_task_cb(struct Thread* task)
}
}
- // remove thread from used task list
- task_node_leave_list(task);
-
// free task back to allocator
slab_free(&xizi_task_manager.task_allocator, (void*)task);
}
-#ifndef __riscv
/* alloc a new task with init */
-extern void trap_return(void);
-__attribute__((optimize("O0"))) void task_prepare_enter()
+static struct Thread* _new_thread(struct MemSpace* pmemspace)
{
- DEBUG_PRINTF("task_prepare_enter\n");
- xizi_leave_kernel();
- trap_return();
-}
-#endif
-
-static struct Thread* _new_task_cb(struct MemSpace* pmemspace)
-{
- // alloc task space
- struct Thread* task = _alloc_task_cb();
- if (!task) {
- return NULL;
- }
-
- /* init basic task member */
- doubleListNodeInit(&task->cli_sess_listhead);
- doubleListNodeInit(&task->svr_sess_listhead);
-
- /* when creating a new task, memspace will be freed outside during memory shortage */
- task->memspace = NULL;
-
- /* init main thread of task */
- task->thread_context.task = task;
- // alloc stack page for task
- if ((void*)(task->thread_context.kern_stack_addr = (uintptr_t)kalloc(USER_STACK_SIZE)) == NULL) {
- /* here inside, will no free memspace */
- _dealloc_task_cb(task);
- return NULL;
- }
-
- /* from now on, _new_task_cb() will not generate error */
- /* init vm */
assert(pmemspace != NULL);
- task->memspace = pmemspace;
- task->thread_context.user_stack_idx = -1;
- doubleListNodeInit(&task->memspace_list_node);
- doubleListAddOnBack(&task->memspace_list_node, &pmemspace->thread_list_guard);
- /* set context of main thread stack */
- /// stack bottom
- memset((void*)task->thread_context.kern_stack_addr, 0x00, USER_STACK_SIZE);
+ // alloc task space
+ struct Thread* task = (struct Thread*)slab_alloc(&xizi_task_manager.task_allocator);
+ if (task == NULL) {
+ ERROR("Not enough memory\n");
+ return NULL;
+ }
+
+ // [schedule related]
+ task->tid = xizi_task_manager.next_pid++;
+ if (!init_schedule_node(&task->snode, task)) {
+ ERROR("Not enough memory\n");
+ slab_free(&xizi_task_manager.task_allocator, (void*)task);
+ return NULL;
+ }
+
+ // alloc stack page for task
+ if ((void*)(task->thread_context.kern_stack_addr = (uintptr_t)kalloc_by_ownership(pmemspace->kernspace_mem_usage.tag, USER_STACK_SIZE)) == NULL) {
+ /* here inside, will no free memspace */
+ assert(RBTTREE_DELETE_SUCC == rbt_delete(&g_scheduler.snode_state_pool[INIT], task->snode.snode_id));
+ slab_free(&xizi_task_manager.task_allocator, (void*)task);
+ return NULL;
+ }
+
+ ERROR_FREE
+ {
+ /* init basic task ref member */
+ task->bind_irq = false;
+
+ /* vm & memory member */
+ task->thread_context.user_stack_idx = -1;
+ task->memspace = pmemspace;
+ doubleListNodeInit(&task->memspace_list_node);
+ doubleListAddOnBack(&task->memspace_list_node, &pmemspace->thread_list_guard);
+
+ /* thread context */
+ task->thread_context.task = task;
+ memset((void*)task->thread_context.kern_stack_addr, 0x00, USER_STACK_SIZE);
+ /// stack bottom
#ifndef __riscv
- char* sp = (char*)task->thread_context.kern_stack_addr + USER_STACK_SIZE - 4;
+ char* sp = (char*)task->thread_context.kern_stack_addr + USER_STACK_SIZE - 4;
#else
- char* sp = (char*)task->thread_context.kern_stack_addr + USER_STACK_SIZE;
+ char* sp = (char*)task->thread_context.kern_stack_addr + USER_STACK_SIZE;
#endif
- /// 1. trap frame into stack, for process to nomally return by trap_return
- sp -= sizeof(*task->thread_context.trapframe);
- task->thread_context.trapframe = (struct trapframe*)sp;
+ /// 1. trap frame into stack, for process to nomally return by trap_return
+ /// trapframe (user context)
+ sp -= sizeof(*task->thread_context.trapframe);
+ task->thread_context.trapframe = (struct trapframe*)sp;
- /// 2. context into stack
- sp -= sizeof(*task->thread_context.context);
- task->thread_context.context = (struct context*)sp;
- arch_init_context(task->thread_context.context);
+ /// 2. context into stack
+ // (kernel context)
+ sp -= sizeof(*task->thread_context.context);
+ task->thread_context.context = (struct context*)sp;
+ arch_init_context(task->thread_context.context);
+
+ /* ipc member */
+ doubleListNodeInit(&task->cli_sess_listhead);
+ doubleListNodeInit(&task->svr_sess_listhead);
+ rbtree_init(&task->cli_sess_map);
+ rbtree_init(&task->svr_sess_map);
+ queue_init(&task->sessions_in_handle);
+ queue_init(&task->sessions_to_be_handle);
+ /// server identifier
+ task->server_identifier.meta = NULL;
+ }
+
+ // [name]
return task;
}
-static void _task_set_default_schedule_attr(struct Thread* task)
-{
- task->remain_tick = TASK_CLOCK_TICK;
- task->maxium_tick = TASK_CLOCK_TICK * 10;
- task->state = READY;
- task->priority = TASK_DEFAULT_PRIORITY;
- task_node_add_to_ready_list_head(task);
-}
+struct TaskLifecycleOperations task_lifecycle_ops = {
+ .new_thread = _new_thread,
+ .free_thread = _free_thread,
+};
static void task_state_set_running(struct Thread* task)
{
- assert(task != NULL && task->state == READY);
- task->state = RUNNING;
- task_node_leave_list(task);
- doubleListAddOnHead(&task->node, &xizi_task_manager.task_running_list_head);
+ assert(task != NULL && task->snode.state == READY);
+ assert(task_trans_sched_state(&task->snode, //
+ &g_scheduler.snode_state_pool[READY], //
+ &g_scheduler.snode_state_pool[RUNNING], RUNNING));
+}
+
+bool rbt_in_queue(RbtNode* node, void* data)
+{
+ Queue* queue = (Queue*)data;
+ return enqueue(queue, node->key, node->data);
+}
+
+extern void show_tasks(void);
+static void central_trans_task_state()
+{
+ Queue tmp_queue;
+ queue_init(&tmp_queue);
+ rbt_traverse(&g_scheduler.state_trans_ref_map, rbt_in_queue, (void*)&tmp_queue);
+
+ while (!queue_is_empty(&tmp_queue)) {
+ struct Thread* thd = (struct Thread*)queue_front(&tmp_queue)->data;
+ struct ScheduleNode* snode = &thd->snode;
+ assert(cur_cpu()->task != NULL);
+ if (snode->state == RUNNING && cur_cpu()->task->tid != thd->tid) {
+ dequeue(&tmp_queue);
+ continue;
+ }
+
+ Queue* trans_queue = &snode->state_trans_signal_queue;
+ while (!queue_is_empty(trans_queue)) {
+ QueueNode* cur_qnode = queue_front(trans_queue);
+ enum ThreadState next_state = cur_qnode->key;
+ switch (next_state) {
+ case READY: {
+ if (snode->state == RUNNING || snode->state == READY) {
+ task_into_ready(thd);
+ } else {
+ ERROR("Thread %s(%d) Error trans to READY(from %d)\n", thd->name, thd->tid, snode->state);
+ }
+ break;
+ }
+ case BLOCKED: {
+ if (snode->sched_context.unblock_signals > 0) {
+ snode->sched_context.unblock_signals--;
+ task_into_ready(thd);
+ } else {
+ task_block(thd);
+ }
+ break;
+ }
+ case SLEEPING: {
+ /// @todo support sleep
+ break;
+ }
+ case TRANS_WAKING: {
+ if (snode->state == BLOCKED) {
+ task_into_ready(thd);
+ } else {
+ snode->sched_context.unblock_signals++;
+ task_into_ready(thd);
+ }
+ break;
+ }
+ case DEAD: {
+ /// @todo
+ break;
+ }
+ default:
+ break;
+ }
+
+ dequeue(trans_queue);
+ }
+
+ assert(RBTTREE_DELETE_SUCC == rbt_delete(&g_scheduler.state_trans_ref_map, thd->tid));
+ dequeue(&tmp_queue);
+ }
}
#ifdef __riscv
@@ -307,7 +390,7 @@ static void _scheduler(struct SchedulerRightGroup right_group)
next_task = NULL;
/* find next runnable task */
assert(cur_cpu()->task == NULL);
- if (next_task_emergency != NULL && next_task_emergency->state == READY) {
+ if (next_task_emergency != NULL && next_task_emergency->snode.state == READY) {
next_task = next_task_emergency;
} else {
next_task = xizi_task_manager.next_runnable_task();
@@ -323,6 +406,7 @@ static void _scheduler(struct SchedulerRightGroup right_group)
}
/* run the chosen task */
+ // DEBUG_PRINTF("Thread %s(%d) to RUNNING\n", next_task->name, next_task->tid);
task_state_set_running(next_task);
cpu->task = next_task;
@@ -332,80 +416,23 @@ static void _scheduler(struct SchedulerRightGroup right_group)
assert(next_task->memspace->pgdir.pd_addr != NULL);
p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->memspace->pgdir.pd_addr));
-
context_switch(&cpu->scheduler, next_task->thread_context.context);
- assert(next_task->state != RUNNING);
+ central_trans_task_state();
+ cpu->task = NULL;
}
}
-static void _task_yield_noschedule(struct Thread* task, bool blocking)
-{
- assert(task != NULL);
- /// @warning only support current task yield now
- assert(task == cur_cpu()->task && task->state == RUNNING);
-
- // rearrage current task position
- task_node_leave_list(task);
- if (task->state == RUNNING) {
- task->state = READY;
- }
- task->remain_tick = TASK_CLOCK_TICK;
- cur_cpu()->task = NULL;
- task_node_add_to_ready_list_back(task);
-}
-
-static void _task_block(struct double_list_node* head, struct Thread* task)
-{
- assert(head != NULL);
- assert(task != NULL);
- assert(task->state != RUNNING);
- task_node_leave_list(task);
- task->state = BLOCKED;
- doubleListAddOnHead(&task->node, head);
-}
-
-static void _task_unblock(struct Thread* task)
-{
- assert(task != NULL);
- assert(task->state == BLOCKED);
- task_node_leave_list(task);
- task->state = READY;
- task_node_add_to_ready_list_back(task);
-}
-
/// @brief @warning not tested function
/// @param priority
static void _set_cur_task_priority(int priority)
{
- if (priority < 0 || priority >= TASK_MAX_PRIORITY) {
- ERROR("priority is invalid\n");
- return;
- }
-
- struct Thread* current_task = cur_cpu()->task;
- assert(current_task != NULL && current_task->state == RUNNING);
-
- task_node_leave_list(current_task);
-
- current_task->priority = priority;
-
- task_node_add_to_ready_list_back(current_task);
-
return;
}
struct XiziTaskManager xizi_task_manager = {
.init = _task_manager_init,
- .new_task_cb = _new_task_cb,
- .free_pcb = _dealloc_task_cb,
- .task_set_default_schedule_attr = _task_set_default_schedule_attr,
-
.next_runnable_task = max_priority_runnable_task,
.task_scheduler = _scheduler,
-
- .task_block = _task_block,
- .task_unblock = _task_unblock,
- .task_yield_noschedule = _task_yield_noschedule,
.set_cur_task_priority = _set_cur_task_priority
};
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/tools/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/tools/Makefile
new file mode 100644
index 000000000..a6e840e59
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/softkernel/tools/Makefile
@@ -0,0 +1,4 @@
+
+SRC_FILES := queue.c rbtree.c
+
+include $(KERNEL_ROOT)/compiler.mk
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/tools/queue.c b/Ubiquitous/XiZi_AIoT/softkernel/tools/queue.c
new file mode 100644
index 000000000..54af4b41d
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/softkernel/tools/queue.c
@@ -0,0 +1,79 @@
+
+
+#include "actracer.h"
+#include "assert.h"
+
+#include "queue.h"
+
+struct QueueFactory {
+ TraceTag tag;
+ struct slab_allocator queue_ele_allocator;
+};
+static struct QueueFactory queue_factory;
+
+void module_queue_factory_init(TraceTag* _softkernel_tag)
+{
+ CreateResourceTag(&queue_factory.tag, _softkernel_tag, "GlobalQueueFactory", TRACER_SYSOBJECT, &queue_factory);
+ slab_init(&queue_factory.queue_ele_allocator, sizeof(struct QueueNode), "QueueNodeAllocator");
+}
+
+void queue_init(Queue* queue)
+{
+ queue->front = NULL;
+ queue->rear = NULL;
+ queue->nr_ele = 0;
+}
+
+struct QueueNode* queue_front(Queue* queue)
+{
+ return queue->front;
+}
+
+bool queue_is_empty(Queue* queue)
+{
+ if (queue->front == NULL) {
+ assert(queue->nr_ele == 0);
+ return true;
+ }
+
+ return false;
+}
+
+bool dequeue(Queue* queue)
+{
+ struct QueueNode* temp = queue->front;
+
+ if (queue->front == NULL) {
+ return false;
+ }
+
+ if (queue->front == queue->rear)
+ queue->front = queue->rear = NULL;
+ else
+ queue->front = queue->front->next;
+
+ queue->nr_ele--;
+ slab_free(&queue_factory.queue_ele_allocator, (void*)temp);
+ return true;
+}
+
+bool enqueue(Queue* queue, uintptr_t key, void* data)
+{
+ QueueNode* temp = (struct QueueNode*)slab_alloc(&queue_factory.queue_ele_allocator);
+ if (temp == NULL) {
+ return false;
+ }
+ temp->key = key;
+ temp->data = data;
+ temp->next = NULL;
+
+ if (queue->front == NULL && queue->rear == NULL) {
+ queue->front = queue->rear = temp;
+ } else {
+ queue->rear->next = temp;
+ queue->rear = temp;
+ }
+
+ queue->nr_ele++;
+ return true;
+}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/tools/rbtree.c b/Ubiquitous/XiZi_AIoT/softkernel/tools/rbtree.c
new file mode 100644
index 000000000..b3e356465
--- /dev/null
+++ b/Ubiquitous/XiZi_AIoT/softkernel/tools/rbtree.c
@@ -0,0 +1,484 @@
+
+#include
+
+#include "assert.h"
+#include "rbtree.h"
+
+struct RbtFactory {
+ TraceTag tag;
+ struct slab_allocator rbtnode_ele_allocator;
+};
+
+static struct RbtFactory rbt_factory;
+
+void module_rbt_factory_init(TraceTag* _softkernel_tag)
+{
+ CreateResourceTag(&rbt_factory.tag, _softkernel_tag, "GlobalRbtFactory", TRACER_SYSOBJECT, &rbt_factory);
+ slab_init(&rbt_factory.rbtnode_ele_allocator, sizeof(struct RbtNode), "RbtNodeAllocator");
+}
+
+void delete_case1(RbtTree* tree, RbtNode* node);
+void delete_case2(RbtTree* tree, RbtNode* node);
+void delete_case3(RbtTree* tree, RbtNode* node);
+void delete_case4(RbtTree* tree, RbtNode* node);
+void delete_case5(RbtTree* tree, RbtNode* node);
+void delete_case6(RbtTree* tree, RbtNode* node);
+
+static inline enum rbt_type get_color(RbtNode* node)
+{
+ if (node == NULL)
+ return BLACK;
+ else
+ return node->color;
+}
+
+static inline void set_color(enum rbt_type color, RbtNode* node)
+{
+ assert(node != NULL);
+ node->color = color;
+}
+
+static inline RbtNode* get_parent(RbtNode* node)
+{
+ assert(node != NULL);
+ return node->parent;
+}
+
+static inline void set_parent(RbtNode* parent, RbtNode* node)
+{
+ assert(node != NULL);
+ node->parent = parent;
+}
+
+static int is_root(RbtNode* node)
+{
+ assert(node != NULL);
+ return (get_parent(node) == NULL);
+}
+
+static inline int is_black(RbtNode* node)
+{
+ assert(node != NULL);
+ return (get_color(node) == BLACK);
+}
+
+static inline int is_red(RbtNode* node)
+{
+ assert(node != NULL);
+ return (get_color(node) == RED);
+}
+
+RbtNode* sibling(RbtNode* node)
+{
+ assert(node != NULL);
+ assert(node->parent != NULL); /* Root node has no sibling */
+ if (node == node->parent->left)
+ return node->parent->right;
+ else
+ return node->parent->left;
+}
+static inline RbtNode* get_min(RbtNode* node)
+{
+ assert(node != NULL);
+ while (node->left) {
+ node = node->left;
+ }
+ return node;
+}
+
+static inline RbtNode* get_max(RbtNode* node)
+{
+ assert(node != NULL);
+ while (node->right) {
+ node = node->right;
+ }
+ return node;
+}
+
+RbtNode* rbtree_min(RbtTree* tree)
+{
+ if (tree->root == NULL)
+ return NULL;
+ else {
+ return get_min(tree->root);
+ }
+}
+
+RbtNode* rbtree_max(RbtTree* tree)
+{
+ if (tree->root == NULL)
+ return NULL;
+ else {
+ return get_max(tree->root);
+ }
+}
+
+RbtNode* rbtree_prev(RbtNode* node)
+{
+ assert(node != NULL);
+ if (node->left) {
+ return get_max(node->left);
+ } else {
+ RbtNode* parent;
+ while ((parent = get_parent(node)) && parent->left == node) {
+ node = parent;
+ }
+ return parent;
+ }
+}
+
+RbtNode* rbtree_next(RbtNode* node)
+{
+ assert(node != NULL);
+
+ if (node->right)
+ return get_min(node->right);
+ else {
+ RbtNode* parent = NULL;
+ while ((parent = get_parent(node)) != NULL && parent->right == node) {
+ node = parent;
+ }
+ return parent;
+ }
+}
+
+RbtNode* rbtree_createnode(uintptr_t key, void* data)
+{
+ RbtNode* newnode = slab_alloc(&rbt_factory.rbtnode_ele_allocator);
+ if (newnode == NULL)
+ return NULL;
+
+ newnode->key = key;
+ newnode->data = data;
+ newnode->parent = NULL;
+ newnode->left = NULL;
+ newnode->right = NULL;
+ return newnode;
+}
+
+static inline int compare(uintptr_t key_a, uintptr_t key_b)
+{
+ if (key_a > key_b)
+ return 1;
+ else if (key_a == key_b)
+ return 0;
+ else
+ return -1;
+}
+
+RbtNode* do_lookup(uintptr_t key,
+ RbtTree* tree,
+ RbtNode** pparent)
+{
+ RbtNode* current = tree->root;
+
+ while (current) {
+ int ret = compare(current->key, key);
+ if (ret == 0)
+ return current;
+ else {
+ if (pparent != NULL) {
+ *pparent = current;
+ }
+ if (ret < 0)
+ current = current->right;
+ else
+ current = current->left;
+ }
+ }
+ return NULL;
+}
+
+RbtNode* rbt_search(RbtTree* tree, uintptr_t key)
+{
+ RbtNode* node;
+ node = do_lookup(key, tree, NULL);
+ return node;
+}
+
+static void set_child(RbtTree* tree, RbtNode* node, RbtNode* child)
+{
+ int ret = compare(node->key, child->key);
+ assert(ret != 0);
+
+ if (ret > 0) {
+ node->left = child;
+ } else {
+ node->right = child;
+ }
+}
+
+static void rotate_left(RbtNode* node, RbtTree* tree)
+{
+ RbtNode* p = node;
+ RbtNode* q = node->right;
+ RbtNode* parent = node->parent;
+ if (parent == NULL) {
+ tree->root = q;
+ } else {
+ if (parent->left == p)
+ parent->left = q;
+ else
+ parent->right = q;
+ }
+ set_parent(parent, q);
+ set_parent(q, p);
+
+ p->right = q->left;
+ if (q->left)
+ set_parent(p, q->left);
+ q->left = p;
+}
+
+static void rotate_right(RbtNode* node, RbtTree* tree)
+{
+ RbtNode* p = node;
+ RbtNode* q = node->left; /* can't be NULL */
+ RbtNode* parent = get_parent(p);
+
+ if (!is_root(p)) {
+ if (parent->left == p)
+ parent->left = q;
+ else
+ parent->right = q;
+ } else
+ tree->root = q;
+ set_parent(parent, q);
+ set_parent(q, p);
+
+ p->left = q->right;
+ if (p->left)
+ set_parent(p, p->left);
+ q->right = p;
+}
+
+void rbtree_init(RbtTree* tree)
+{
+ tree->root = NULL;
+ tree->nr_ele = 0;
+}
+
+RbtNode* __rbtree_insert(RbtNode* node, RbtTree* tree)
+{
+ RbtNode* samenode = NULL;
+ RbtNode* parent = NULL;
+
+ samenode = do_lookup(node->key, tree, &parent);
+ if (samenode != NULL)
+ return samenode;
+
+ node->left = node->right = NULL;
+ set_color(RED, node);
+ set_parent(parent, node);
+
+ if (parent == NULL)
+ tree->root = node;
+ else {
+ set_child(tree, parent, node);
+ }
+
+ while ((parent = get_parent(node)) != NULL && parent->color == RED) {
+ RbtNode* grandpa = get_parent(parent); // grandpa must be existed
+ // because root is black ,and parent is red,
+ // parent can not be root of tree. and parent is red,so grandpa must be black
+ if (parent == grandpa->left) {
+ RbtNode* uncle = grandpa->right;
+ if (uncle && get_color(uncle) == RED) {
+ set_color(RED, grandpa);
+ set_color(BLACK, parent);
+ set_color(BLACK, uncle);
+ node = grandpa;
+ } else {
+ if (node == parent->right) {
+ rotate_left(parent, tree);
+ node = parent;
+ parent = get_parent(parent);
+ }
+ set_color(BLACK, parent);
+ set_color(RED, grandpa);
+ rotate_right(grandpa, tree);
+ }
+
+ } else {
+ RbtNode* uncle = grandpa->left;
+ if (uncle && uncle->color == RED) {
+ set_color(RED, grandpa);
+ set_color(BLACK, parent);
+ set_color(BLACK, uncle);
+ node = grandpa;
+ } else {
+ if (node == parent->left) {
+ rotate_right(parent, tree);
+ node = parent;
+ parent = get_parent(node);
+ }
+ set_color(BLACK, parent);
+ set_color(RED, grandpa);
+ rotate_left(grandpa, tree);
+ }
+ }
+ }
+
+ set_color(BLACK, tree->root);
+ return NULL;
+}
+
+int rbt_insert(RbtTree* tree, uintptr_t key, void* data)
+{
+ if (rbt_search(tree, key) != NULL) {
+ return RBTTREE_INSERT_EXISTED;
+ }
+
+ RbtNode* node = rbtree_createnode(key, data);
+ RbtNode* samenode = NULL;
+ if (node == NULL)
+ return RBTTREE_INSERT_FAILED;
+ else
+ samenode = __rbtree_insert(node, tree);
+
+ assert(samenode == NULL);
+
+ tree->nr_ele++;
+ return RBTTREE_INSERT_SECC;
+}
+
+void replace_node(RbtTree* t, RbtNode* oldn, RbtNode* newn)
+{
+ if (oldn->parent == NULL) {
+ t->root = newn;
+ } else {
+ if (oldn == oldn->parent->left)
+ oldn->parent->left = newn;
+ else
+ oldn->parent->right = newn;
+ }
+ if (newn != NULL) {
+ newn->parent = oldn->parent;
+ }
+}
+
+void delete_case1(RbtTree* tree, RbtNode* node)
+{
+ if (node->parent == NULL)
+ return;
+ else
+ delete_case2(tree, node);
+}
+
+void delete_case2(RbtTree* tree, RbtNode* node)
+{
+ if (get_color(sibling(node)) == RED) {
+ node->parent->color = RED;
+ sibling(node)->color = BLACK;
+ if (node == node->parent->left) {
+ rotate_left(node->parent, tree);
+ } else {
+ rotate_right(node->parent, tree);
+ }
+ }
+ delete_case3(tree, node);
+}
+
+void delete_case3(RbtTree* tree, RbtNode* node)
+{
+ if (node->parent->color == BLACK && get_color(sibling(node)) == BLACK && get_color(sibling(node)->right) == BLACK && get_color(sibling(node)->left) == BLACK) {
+ sibling(node)->color = RED;
+ delete_case1(tree, node->parent);
+ } else {
+ delete_case4(tree, node);
+ }
+}
+
+void delete_case4(RbtTree* t, RbtNode* n)
+{
+ if (get_color(n->parent) == RED && get_color(sibling(n)) == BLACK && get_color(sibling(n)->left) == BLACK && get_color(sibling(n)->right) == BLACK) {
+ sibling(n)->color = RED; // sibling's two son is black ,so it can changed to red
+ n->parent->color = BLACK;
+ } else
+ delete_case5(t, n);
+}
+
+void delete_case5(RbtTree* t, RbtNode* n)
+{
+ if (n == n->parent->left && get_color(sibling(n)) == BLACK && get_color(sibling(n)->left) == RED && get_color(sibling(n)->right) == BLACK) {
+ sibling(n)->color = RED;
+ sibling(n)->left->color = BLACK;
+ rotate_right(sibling(n), t);
+ } else if (n == n->parent->right && get_color(sibling(n)) == BLACK && get_color(sibling(n)->right) == RED && get_color(sibling(n)->left) == BLACK) {
+ sibling(n)->color = RED;
+ sibling(n)->right->color = BLACK;
+ rotate_left(sibling(n), t);
+ }
+ delete_case6(t, n);
+}
+
+void delete_case6(RbtTree* t, RbtNode* n)
+{
+ sibling(n)->color = get_color(n->parent);
+ n->parent->color = BLACK;
+ if (n == n->parent->left) {
+ assert(get_color(sibling(n)->right) == RED);
+ sibling(n)->right->color = BLACK;
+ rotate_left(n->parent, t);
+ } else {
+ assert(get_color(sibling(n)->left) == RED);
+ sibling(n)->left->color = BLACK;
+ rotate_right(n->parent, t);
+ }
+}
+
+void __rbtree_remove(RbtNode* node, RbtTree* tree)
+{
+ RbtNode* left = node->left;
+ RbtNode* right = node->right;
+ RbtNode* child = NULL;
+ if (left != NULL && right != NULL) {
+ RbtNode* next = get_min(right);
+ node->key = next->key;
+ node->data = next->data;
+ node = next;
+ }
+
+ assert(node->left == NULL || node->right == NULL);
+ child = (node->right == NULL ? node->left : node->right);
+ if (get_color(node) == BLACK) {
+ set_color(get_color(child), node);
+ delete_case1(tree, node);
+ }
+ replace_node(tree, node, child);
+ if (node->parent == NULL && child != NULL) // node is root,root should be black
+ set_color(BLACK, child);
+ slab_free(&rbt_factory.rbtnode_ele_allocator, (void*)node);
+}
+
+int rbt_delete(RbtTree* tree, uintptr_t key)
+{
+ RbtNode* node = do_lookup(key, tree, NULL);
+ if (node == NULL)
+ return RBTTREE_DELETE_FAILED;
+ else
+ __rbtree_remove(node, tree);
+
+ tree->nr_ele--;
+ if (rbt_is_empty(tree)) {
+ assert(tree->root == NULL);
+ }
+ return RBTTREE_DELETE_SUCC;
+}
+
+void rbt_traverse_inner(RbtNode* node, rbt_traverse_fn fn, void* data)
+{
+ if (node == NULL) {
+ return;
+ }
+
+ if (fn(node, data)) {
+ rbt_traverse_inner(node->left, fn, data);
+ rbt_traverse_inner(node->right, fn, data);
+ }
+}
+
+void rbt_traverse(RbtTree* tree, rbt_traverse_fn fn, void* data)
+{
+ rbt_traverse_inner(tree->root, fn, data);
+}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c
index 5ddcd649f..f282a4a28 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c
@@ -77,7 +77,6 @@ __attribute__((optimize("O0"))) void dabort_handler(struct trapframe* r)
xizi_enter_kernel();
sys_exit(cur_task);
- assert(cur_cpu()->task == NULL);
#ifndef __riscv
context_switch(&cur_task->thread_context.context, cur_cpu()->scheduler);
#else
@@ -110,7 +109,6 @@ __attribute__((optimize("O0"))) void iabort_handler(struct trapframe* r)
xizi_enter_kernel();
sys_exit(cur_task);
- assert(cur_cpu()->task == NULL);
#ifndef __riscv
context_switch(&cur_task->thread_context.context, cur_cpu()->scheduler);
#else
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c
index eba875e07..4531f130c 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c
@@ -62,6 +62,12 @@ void hw_current_second(uintptr_t* second)
*second = p_clock_driver->get_second();
}
+bool count_down_sleeping_task(RbtNode* node, void* data)
+{
+ /// @todo implement
+ return false;
+}
+
uint64_t global_tick = 0;
int xizi_clock_handler(int irq, void* tf, void* arg)
{
@@ -69,14 +75,29 @@ int xizi_clock_handler(int irq, void* tf, void* arg)
if (p_clock_driver->is_timer_expired()) {
p_clock_driver->clear_clock_intr();
global_tick++;
+
+ // handle current thread
struct Thread* current_task = cur_cpu()->task;
if (current_task) {
- current_task->remain_tick--;
- current_task->maxium_tick--;
- if (current_task->remain_tick == 0) {
- xizi_task_manager.task_yield_noschedule(current_task, false);
+ struct ScheduleNode* snode = ¤t_task->snode;
+ snode->sched_context.remain_tick--;
+ if (snode->sched_context.remain_tick == 0) {
+ THREAD_TRANS_STATE(current_task, READY);
}
}
+
+ // todo: cpu 0 will handle sleeping thread
+ rbt_traverse(&g_scheduler.snode_state_pool[SLEEPING], count_down_sleeping_task, NULL);
+
+ // DOUBLE_LIST_FOR_EACH_ENTRY(thread, &xizi_task_manager.task_sleep_list_head, node)
+ // {
+ // assert(thread->state == SLEEPING);
+ // thread->sleep_context.remain_ms--;
+ // if (thread->sleep_context.remain_ms <= 0) {
+ // xizi_task_manager.task_unblock(thread);
+ // break;
+ // }
+ // }
}
return 0;
}
\ No newline at end of file
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c
index 07fe4dcef..2e1b93e9f 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c
@@ -88,8 +88,8 @@ void intr_irq_dispatch(struct trapframe* tf)
// finish irq.
p_intr_driver->hw_after_irq(int_info);
- if (cur_cpu()->task == NULL || current_task->state != RUNNING) {
- cur_cpu()->task = NULL;
+ assert(cur_cpu()->task == current_task && current_task->snode.state == RUNNING);
+ if (!queue_is_empty(¤t_task->snode.state_trans_signal_queue)) {
#ifndef __riscv
context_switch(¤t_task->thread_context.context, cur_cpu()->scheduler);
#else
diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c
index 6b9ce865c..be44d93ad 100644
--- a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c
+++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c
@@ -58,16 +58,18 @@ void software_irq_dispatch(struct trapframe* tf)
// get current task
struct Thread* cur_task = cur_cpu()->task;
/// @todo: Handle dead task
+
int syscall_num = -1;
- if (cur_task && cur_task->state != DEAD) {
+ if (cur_task && cur_task->snode.state != DEAD) {
cur_task->thread_context.trapframe = tf;
// call syscall
+
int ret = arch_syscall(cur_task->thread_context.trapframe, &syscall_num);
arch_set_return(tf, ret);
}
- if ((cur_cpu()->task == NULL && cur_task != NULL) || cur_task->state != RUNNING) {
- cur_cpu()->task = NULL;
+ assert(cur_cpu()->task == cur_task && cur_task->snode.state == RUNNING);
+ if (!queue_is_empty(&cur_task->snode.state_trans_signal_queue)) {
#ifndef __riscv
context_switch(&cur_task->thread_context.context, cur_cpu()->scheduler);
#else
@@ -81,4 +83,4 @@ void software_irq_dispatch(struct trapframe* tf)
assert(cur_task == cur_cpu()->task);
xizi_leave_kernel();
-}
+}
\ No newline at end of file