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