summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShell <[email protected]>2023-01-09 10:08:55 +0800
committerGitHub <[email protected]>2023-01-08 21:08:55 -0500
commit7450ef6c4d71f992444d27f4a26c16f813ed8e55 (patch)
tree1d9b450d85c2c048cae2410e97ef9edfc2868323
parent7f9ccd3c809afa6b54f0d453f2edcc8367a6aeb8 (diff)
[rt-smart] kernel virtual memory management layer (#6809)
synchronize virtual memory system works. adding kernel virtual memory management layer for page-based MMU enabled architecture porting libcpu MMU codes porting lwp memory related codes
-rw-r--r--bsp/allwinner/d1s/.config163
-rw-r--r--bsp/allwinner/d1s/board/board.c13
-rw-r--r--bsp/allwinner/d1s/board/board.h1
-rw-r--r--bsp/allwinner/d1s/link.lds20
-rw-r--r--bsp/allwinner/d1s/rtconfig.h31
-rw-r--r--bsp/allwinner/d1s/rtconfig.py4
-rw-r--r--bsp/qemu-vexpress-a9/.config796
-rw-r--r--bsp/qemu-vexpress-a9/drivers/board.c19
-rw-r--r--bsp/qemu-vexpress-a9/drivers/board.h2
-rwxr-xr-xbsp/qemu-vexpress-a9/qemu-dbg.sh2
-rw-r--r--bsp/qemu-vexpress-a9/rtconfig.h126
-rw-r--r--bsp/qemu-vexpress-a9/rtconfig.py2
-rw-r--r--bsp/qemu-virt64-aarch64/.config627
-rw-r--r--bsp/qemu-virt64-aarch64/drivers/board.c36
-rw-r--r--bsp/qemu-virt64-aarch64/drivers/virt.h1
-rw-r--r--bsp/qemu-virt64-aarch64/qemu-debug.sh2
-rwxr-xr-xbsp/qemu-virt64-aarch64/qemu.sh2
-rw-r--r--bsp/qemu-virt64-aarch64/rtconfig.h109
-rw-r--r--bsp/qemu-virt64-riscv/.config639
-rw-r--r--bsp/qemu-virt64-riscv/applications/test/test_mm/SConscript9
-rw-r--r--bsp/qemu-virt64-riscv/applications/test/test_mm/test_mm.c118
-rw-r--r--bsp/qemu-virt64-riscv/driver/board.c28
-rw-r--r--bsp/qemu-virt64-riscv/driver/board.h13
-rw-r--r--bsp/qemu-virt64-riscv/driver/virt.h1
-rwxr-xr-xbsp/qemu-virt64-riscv/qemu-dbg.sh1
-rw-r--r--bsp/qemu-virt64-riscv/qemu-v-dbg.sh3
-rw-r--r--bsp/qemu-virt64-riscv/rtconfig.h113
-rw-r--r--bsp/raspberry-pi/raspi3-64/.config1
-rw-r--r--bsp/raspberry-pi/raspi3-64/driver/board.c5
-rw-r--r--bsp/raspberry-pi/raspi3-64/rtconfig.h1
-rw-r--r--bsp/raspberry-pi/raspi4-32/.config193
-rw-r--r--bsp/raspberry-pi/raspi4-32/rtconfig.h19
-rw-r--r--bsp/raspberry-pi/raspi4-64/.config193
-rw-r--r--bsp/raspberry-pi/raspi4-64/driver/board.c5
-rw-r--r--bsp/raspberry-pi/raspi4-64/rtconfig.h19
-rw-r--r--bsp/rockchip/rk3568/.config191
-rw-r--r--bsp/rockchip/rk3568/driver/board.c5
-rw-r--r--bsp/rockchip/rk3568/rtconfig.h19
-rw-r--r--components/drivers/virtio/virtio.h3
-rw-r--r--components/lwp/arch/aarch64/cortex-a/lwp_arch.c34
-rw-r--r--components/lwp/arch/arm/common/reloc.c11
-rw-r--r--components/lwp/arch/arm/cortex-a/lwp_arch.c50
-rw-r--r--components/lwp/arch/risc-v/rv64/lwp_arch.c55
-rw-r--r--components/lwp/arch/risc-v/rv64/lwp_arch.h9
-rw-r--r--components/lwp/arch/risc-v/rv64/reloc.c11
-rw-r--r--components/lwp/ioremap.c72
-rw-r--r--components/lwp/ioremap.h5
-rw-r--r--components/lwp/lwp.c18
-rw-r--r--components/lwp/lwp.h13
-rw-r--r--components/lwp/lwp_arch_comm.h8
-rw-r--r--components/lwp/lwp_mm_area.c122
-rw-r--r--components/lwp/lwp_mm_area.h53
-rw-r--r--components/lwp/lwp_shm.c73
-rw-r--r--components/lwp/lwp_syscall.c32
-rw-r--r--components/lwp/lwp_user_mm.c479
-rw-r--r--components/lwp/lwp_user_mm.h33
-rw-r--r--components/lwp/page.c424
-rw-r--r--components/lwp/page.h28
-rw-r--r--components/mm/SConscript21
-rw-r--r--components/mm/avl_adpt.c178
-rw-r--r--components/mm/avl_adpt.h37
-rw-r--r--components/mm/mm_aspace.c743
-rw-r--r--components/mm/mm_aspace.h202
-rw-r--r--components/mm/mm_fault.c135
-rw-r--r--components/mm/mm_fault.h55
-rw-r--r--components/mm/mm_flag.h89
-rw-r--r--components/mm/mm_object.c109
-rw-r--r--components/mm/mm_page.c644
-rw-r--r--components/mm/mm_page.h81
-rw-r--r--components/mm/mm_private.h94
-rw-r--r--components/utilities/libadt/SConscript8
-rw-r--r--components/utilities/libadt/avl.c231
-rw-r--r--components/utilities/libadt/avl.h116
-rw-r--r--include/rtdef.h4
-rw-r--r--include/rthw.h5
-rw-r--r--libcpu/aarch64/common/context_gcc.S27
-rw-r--r--libcpu/aarch64/common/cpu_ops_common.h2
-rw-r--r--libcpu/aarch64/common/cpuport.h15
-rw-r--r--libcpu/aarch64/common/interrupt.c14
-rw-r--r--libcpu/aarch64/common/mmu.c1056
-rw-r--r--libcpu/aarch64/common/mmu.h129
-rw-r--r--libcpu/aarch64/common/tlb.h80
-rw-r--r--libcpu/aarch64/common/trap.c49
-rw-r--r--libcpu/aarch64/cortex-a/entry_point.S19
-rw-r--r--libcpu/arm/cortex-a/context_gcc.S4
-rw-r--r--libcpu/arm/cortex-a/cpuport.h2
-rw-r--r--libcpu/arm/cortex-a/interrupt.c7
-rw-r--r--libcpu/arm/cortex-a/mmu.c665
-rw-r--r--libcpu/arm/cortex-a/mmu.h51
-rw-r--r--libcpu/arm/cortex-a/start_gcc.S25
-rw-r--r--libcpu/arm/cortex-a/tlb.h48
-rw-r--r--libcpu/arm/cortex-a/trap.c28
-rw-r--r--libcpu/risc-v/t-head/c906/backtrace.c137
-rw-r--r--libcpu/risc-v/t-head/c906/context_gcc.S4
-rw-r--r--libcpu/risc-v/t-head/c906/cpuport.c7
-rw-r--r--libcpu/risc-v/t-head/c906/cpuport.h8
-rw-r--r--libcpu/risc-v/t-head/c906/encoding.h2
-rw-r--r--libcpu/risc-v/t-head/c906/interrupt_gcc.S2
-rw-r--r--libcpu/risc-v/t-head/c906/mmu.c818
-rw-r--r--libcpu/risc-v/t-head/c906/mmu.h96
-rw-r--r--libcpu/risc-v/t-head/c906/riscv_mmu.c12
-rw-r--r--libcpu/risc-v/t-head/c906/riscv_mmu.h45
-rw-r--r--libcpu/risc-v/t-head/c906/sbi.c85
-rw-r--r--libcpu/risc-v/t-head/c906/sbi.h6
-rw-r--r--libcpu/risc-v/t-head/c906/tlb.h61
-rw-r--r--libcpu/risc-v/t-head/c906/trap.c77
-rw-r--r--libcpu/risc-v/virt64/backtrace.c7
-rw-r--r--libcpu/risc-v/virt64/context_gcc.S4
-rw-r--r--libcpu/risc-v/virt64/mmu.c726
-rw-r--r--libcpu/risc-v/virt64/mmu.h84
-rw-r--r--libcpu/risc-v/virt64/riscv_mmu.c14
-rw-r--r--libcpu/risc-v/virt64/riscv_mmu.h13
-rw-r--r--libcpu/risc-v/virt64/sbi.c47
-rw-r--r--libcpu/risc-v/virt64/sbi.h4
-rw-r--r--libcpu/risc-v/virt64/start.c24
-rw-r--r--libcpu/risc-v/virt64/startup_gcc.S6
-rw-r--r--libcpu/risc-v/virt64/syscall_c.c1
-rw-r--r--libcpu/risc-v/virt64/tlb.h61
-rw-r--r--libcpu/risc-v/virt64/trap.c81
-rw-r--r--src/Kconfig10
-rw-r--r--src/cpu.c2
121 files changed, 5694 insertions, 6788 deletions
diff --git a/bsp/allwinner/d1s/.config b/bsp/allwinner/d1s/.config
index 188d305a04..008bf69488 100644
--- a/bsp/allwinner/d1s/.config
+++ b/bsp/allwinner/d1s/.config
@@ -60,6 +60,7 @@ CONFIG_RT_USING_MESSAGEQUEUE=y
#
# Memory Management
#
+CONFIG_RT_PAGE_MAX_ORDER=11
CONFIG_RT_USING_MEMPOOL=y
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
@@ -90,9 +91,8 @@ CONFIG_RT_USING_CACHE=y
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
# CONFIG_RT_USING_CPU_FFS is not set
CONFIG_ARCH_MM_MMU=y
-CONFIG_RT_USING_USERSPACE=y
CONFIG_KERNEL_VADDR_START=0x150000000
-CONFIG_PV_OFFSET=0
+CONFIG_PV_OFFSET=0x0
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_RISCV64=y
@@ -570,6 +570,7 @@ CONFIG_RT_USING_POSIX_PIPE_SIZE=512
# CONFIG_PKG_USING_KMULTI_RTIMER is not set
# CONFIG_PKG_USING_TFDB is not set
# CONFIG_PKG_USING_QPC is not set
+# CONFIG_PKG_USING_AGILE_UPGRADE is not set
#
# peripheral libraries and drivers
@@ -744,32 +745,170 @@ CONFIG_RT_USING_POSIX_PIPE_SIZE=512
# CONFIG_PKG_USING_RTDUINO is not set
#
-# Sensor libraries
+# Projects
+#
+# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
+# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
+# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
+
+#
+# Sensors
#
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
+# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set
+# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
#
-# Display libraries
+# Display
#
# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
#
-# Timing libraries
+# Timing
#
# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set
#
-# Project libraries
+# Data Processing
+#
+# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set
+# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set
+
+#
+# Data Storage
+#
+
+#
+# Communication
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set
+
+#
+# Device Control
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
+
+#
+# Other
+#
+
+#
+# Signal IO
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set
+
+#
+# Uncategorized
#
-# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
-# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
CONFIG_BOARD_allwinnerd1s=y
-CONFIG_ENABLE_FPU=y
+# CONFIG_ENABLE_FPU is not set
# CONFIG_RT_USING_USERSPACE_32BIT_LIMIT is not set
CONFIG___STACKSIZE__=16384
diff --git a/bsp/allwinner/d1s/board/board.c b/bsp/allwinner/d1s/board/board.c
index f318d5ba10..cff7c8daf5 100644
--- a/bsp/allwinner/d1s/board/board.c
+++ b/bsp/allwinner/d1s/board/board.c
@@ -13,6 +13,7 @@
#include <rtdevice.h>
#include "board.h"
+#include "mm_aspace.h"
#include "tick.h"
#include "drv_uart.h"
@@ -40,8 +41,7 @@ rt_region_t init_page_region =
(rt_size_t)RT_HW_PAGE_END};
// 内核页表
-volatile rt_size_t MMUTable[__SIZE(VPN2_BIT)] __attribute__((aligned(4 * 1024)));
-rt_mmu_info mmu_info;
+extern volatile rt_size_t MMUTable[__SIZE(VPN2_BIT)] __attribute__((aligned(4 * 1024)));
#endif
@@ -71,6 +71,7 @@ void primary_cpu_entry(void)
// 初始化BSS
init_bss();
+ sbi_init();
// 关中断
rt_hw_interrupt_disable();
rt_assert_set_hook(__rt_assert_handler);
@@ -78,18 +79,20 @@ void primary_cpu_entry(void)
entry();
}
+#define IOREMAP_SIZE (1ul << 30)
+
// 这个初始化程序由内核主动调用,此时调度器还未启动,因此在此不能使用依赖线程上下文的函数
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
+ rt_hw_mmu_map_init(&rt_kernel_space, (void *)(USER_VADDR_START - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t *)MMUTable, 0);
rt_page_init(init_page_region);
- rt_hw_mmu_map_init(&mmu_info, (void *)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, (rt_size_t *)MMUTable, 0);
- rt_hw_mmu_kernel_map_init(&mmu_info, 0x00000000UL, USER_VADDR_START - 1);
+ rt_hw_mmu_kernel_map_init(&rt_kernel_space, 0x00000000UL, USER_VADDR_START - 1);
// 将低1GB MMIO区域设置为无Cache与Strong Order访存模式
MMUTable[0] &= ~PTE_CACHE;
MMUTable[0] &= ~PTE_SHARE;
MMUTable[0] |= PTE_SO;
- rt_hw_mmu_switch((void *)MMUTable);
+ rt_hw_aspace_switch(&rt_kernel_space);
#endif
/* initalize interrupt */
rt_hw_interrupt_init();
diff --git a/bsp/allwinner/d1s/board/board.h b/bsp/allwinner/d1s/board/board.h
index 571b3163fa..4300746586 100644
--- a/bsp/allwinner/d1s/board/board.h
+++ b/bsp/allwinner/d1s/board/board.h
@@ -11,6 +11,7 @@
#ifndef BOARD_H__
#define BOARD_H__
+#include <rtthread.h>
#include <rtconfig.h>
extern unsigned int __bss_start;
diff --git a/bsp/allwinner/d1s/link.lds b/bsp/allwinner/d1s/link.lds
index 912e63109e..a9f838120e 100644
--- a/bsp/allwinner/d1s/link.lds
+++ b/bsp/allwinner/d1s/link.lds
@@ -30,7 +30,7 @@ SECTIONS
. = 0x40400000 ;
/* __STACKSIZE__ = 4096; */
-
+ __text_start = .;
.start :
{
*(.start);
@@ -38,7 +38,7 @@ SECTIONS
. = ALIGN(8);
- .text :
+ .text :
{
*(.text) /* remaining code */
*(.text.*) /* remaining code */
@@ -47,7 +47,7 @@ SECTIONS
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t*)
-
+
/* section information for finsh shell */
. = ALIGN(8);
__fsymtab_start = .;
@@ -74,20 +74,22 @@ SECTIONS
_etext = .;
} > SRAM
- .eh_frame_hdr :
- {
- *(.eh_frame_hdr)
+ .eh_frame_hdr :
+ {
+ *(.eh_frame_hdr)
*(.eh_frame_entry)
} > SRAM
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } > SRAM
. = ALIGN(8);
+ __text_end = .;
+ __text_size = __text_end - __text_start;
- .data :
+ .data :
{
*(.data)
*(.data.*)
-
+
*(.data1)
*(.data1.*)
@@ -139,7 +141,7 @@ SECTIONS
. = ALIGN(8);
- .sbss :
+ .sbss :
{
__bss_start = .;
*(.sbss)
diff --git a/bsp/allwinner/d1s/rtconfig.h b/bsp/allwinner/d1s/rtconfig.h
index 2337d5b3f8..2800188b07 100644
--- a/bsp/allwinner/d1s/rtconfig.h
+++ b/bsp/allwinner/d1s/rtconfig.h
@@ -37,6 +37,7 @@
/* Memory Management */
+#define RT_PAGE_MAX_ORDER 11
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
@@ -54,7 +55,7 @@
#define RT_USING_CACHE
#define ARCH_MM_MMU
#define KERNEL_VADDR_START 0x150000000
-#define PV_OFFSET 0
+#define PV_OFFSET 0x0
#define ARCH_RISCV
#define ARCH_RISCV64
@@ -241,19 +242,37 @@
/* Arduino libraries */
-/* Sensor libraries */
+/* Projects */
-/* Display libraries */
+/* Sensors */
-/* Timing libraries */
+/* Display */
-/* Project libraries */
+/* Timing */
+
+
+/* Data Processing */
+
+
+/* Data Storage */
+
+/* Communication */
+
+
+/* Device Control */
+
+
+/* Other */
+
+/* Signal IO */
+
+
+/* Uncategorized */
#define BOARD_allwinnerd1s
-#define ENABLE_FPU
#define __STACKSIZE__ 16384
/* General Drivers Configuration */
diff --git a/bsp/allwinner/d1s/rtconfig.py b/bsp/allwinner/d1s/rtconfig.py
index 09c6467815..062bf2a13c 100644
--- a/bsp/allwinner/d1s/rtconfig.py
+++ b/bsp/allwinner/d1s/rtconfig.py
@@ -38,8 +38,8 @@ if PLATFORM == 'gcc':
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcmodel=medany -march=rv64imafdc -mabi=lp64'
- CFLAGS = DEVICE + ' -fvar-tracking -ffreestanding -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields '
- AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
+ CFLAGS = DEVICE + ' -Wno-cpp -fvar-tracking -ffreestanding -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields '
+ AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__'
LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,_start -T link.lds' + ' -lsupc++ -lgcc -static'
CPATH = ''
LPATH = ''
diff --git a/bsp/qemu-vexpress-a9/.config b/bsp/qemu-vexpress-a9/.config
index eb2a6397a4..8a6201424a 100644
--- a/bsp/qemu-vexpress-a9/.config
+++ b/bsp/qemu-vexpress-a9/.config
@@ -59,6 +59,7 @@ CONFIG_RT_USING_MESSAGEQUEUE=y
#
# Memory Management
#
+CONFIG_RT_PAGE_MAX_ORDER=11
CONFIG_RT_USING_MEMPOOL=y
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
@@ -92,7 +93,6 @@ CONFIG_RT_USING_CPU_FFS=y
CONFIG_ARCH_MM_MMU=y
CONFIG_ARCH_ARM=y
CONFIG_ARCH_ARM_MMU=y
-# CONFIG_RT_USING_USERSPACE is not set
CONFIG_ARCH_ARM_CORTEX_A=y
# CONFIG_RT_SMP_AUTO_BOOT is not set
CONFIG_RT_USING_GIC_V2=y
@@ -160,7 +160,6 @@ CONFIG_RT_USING_DFS_ROMFS=y
# CONFIG_RT_USING_DFS_RAMFS is not set
CONFIG_RT_USING_DFS_TMPFS=y
# CONFIG_RT_USING_FAL is not set
-# CONFIG_RT_USING_LWP is not set
#
# Device Drivers
@@ -173,7 +172,7 @@ CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
CONFIG_RT_USING_SERIAL=y
CONFIG_RT_USING_SERIAL_V1=y
# CONFIG_RT_USING_SERIAL_V2 is not set
-# CONFIG_RT_SERIAL_USING_DMA is not set
+CONFIG_RT_SERIAL_USING_DMA=y
CONFIG_RT_SERIAL_RB_BUFSZ=256
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_HWTIMER is not set
@@ -296,797 +295,6 @@ CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE=y
# CONFIG_RT_USING_UTESTCASES is not set
#
-# RT-Thread online packages
-#
-
-#
-# IoT - internet of things
-#
-# CONFIG_PKG_USING_LWIP is not set
-# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
-# CONFIG_PKG_USING_PAHOMQTT is not set
-# CONFIG_PKG_USING_UMQTT is not set
-# CONFIG_PKG_USING_WEBCLIENT is not set
-# CONFIG_PKG_USING_WEBNET is not set
-# CONFIG_PKG_USING_MONGOOSE is not set
-# CONFIG_PKG_USING_MYMQTT is not set
-# CONFIG_PKG_USING_KAWAII_MQTT is not set
-# CONFIG_PKG_USING_BC28_MQTT is not set
-# CONFIG_PKG_USING_WEBTERMINAL is not set
-# CONFIG_PKG_USING_LIBMODBUS is not set
-# CONFIG_PKG_USING_FREEMODBUS is not set
-# CONFIG_PKG_USING_NANOPB is not set
-
-#
-# Wi-Fi
-#
-
-#
-# Marvell WiFi
-#
-# CONFIG_PKG_USING_WLANMARVELL is not set
-
-#
-# Wiced WiFi
-#
-# CONFIG_PKG_USING_WLAN_WICED is not set
-# CONFIG_PKG_USING_RW007 is not set
-# CONFIG_PKG_USING_COAP is not set
-# CONFIG_PKG_USING_NOPOLL is not set
-# CONFIG_PKG_USING_NETUTILS is not set
-# CONFIG_PKG_USING_CMUX is not set
-# CONFIG_PKG_USING_PPP_DEVICE is not set
-# CONFIG_PKG_USING_AT_DEVICE is not set
-# CONFIG_PKG_USING_ATSRV_SOCKET is not set
-# CONFIG_PKG_USING_WIZNET is not set
-# CONFIG_PKG_USING_ZB_COORDINATOR is not set
-
-#
-# IoT Cloud
-#
-# CONFIG_PKG_USING_ONENET is not set
-# CONFIG_PKG_USING_GAGENT_CLOUD is not set
-# CONFIG_PKG_USING_ALI_IOTKIT is not set
-# CONFIG_PKG_USING_AZURE is not set
-# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
-# CONFIG_PKG_USING_JIOT-C-SDK is not set
-# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
-# CONFIG_PKG_USING_JOYLINK is not set
-# CONFIG_PKG_USING_EZ_IOT_OS is not set
-# CONFIG_PKG_USING_IOTSHARP_SDK is not set
-# CONFIG_PKG_USING_NIMBLE is not set
-# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set
-# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
-# CONFIG_PKG_USING_IPMSG is not set
-# CONFIG_PKG_USING_LSSDP is not set
-# CONFIG_PKG_USING_AIRKISS_OPEN is not set
-# CONFIG_PKG_USING_LIBRWS is not set
-# CONFIG_PKG_USING_TCPSERVER is not set
-# CONFIG_PKG_USING_PROTOBUF_C is not set
-# CONFIG_PKG_USING_DLT645 is not set
-# CONFIG_PKG_USING_QXWZ is not set
-# CONFIG_PKG_USING_SMTP_CLIENT is not set
-# CONFIG_PKG_USING_ABUP_FOTA is not set
-# CONFIG_PKG_USING_LIBCURL2RTT is not set
-# CONFIG_PKG_USING_CAPNP is not set
-# CONFIG_PKG_USING_AGILE_TELNET is not set
-# CONFIG_PKG_USING_NMEALIB is not set
-# CONFIG_PKG_USING_PDULIB is not set
-# CONFIG_PKG_USING_BTSTACK is not set
-# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
-# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
-# CONFIG_PKG_USING_MAVLINK is not set
-# CONFIG_PKG_USING_BSAL is not set
-# CONFIG_PKG_USING_AGILE_MODBUS is not set
-# CONFIG_PKG_USING_AGILE_FTP is not set
-# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
-# CONFIG_PKG_USING_RT_LINK_HW is not set
-# CONFIG_PKG_USING_LORA_PKT_FWD is not set
-# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set
-# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
-# CONFIG_PKG_USING_HM is not set
-# CONFIG_PKG_USING_SMALL_MODBUS is not set
-# CONFIG_PKG_USING_NET_SERVER is not set
-# CONFIG_PKG_USING_ZFTP is not set
-# CONFIG_PKG_USING_WOL is not set
-
-#
-# security packages
-#
-# CONFIG_PKG_USING_MBEDTLS is not set
-# CONFIG_PKG_USING_LIBSODIUM is not set
-# CONFIG_PKG_USING_LIBHYDROGEN is not set
-# CONFIG_PKG_USING_TINYCRYPT is not set
-# CONFIG_PKG_USING_TFM is not set
-# CONFIG_PKG_USING_YD_CRYPTO is not set
-
-#
-# language packages
-#
-
-#
-# JSON: JavaScript Object Notation, a lightweight data-interchange format
-#
-# CONFIG_PKG_USING_CJSON is not set
-# CONFIG_PKG_USING_LJSON is not set
-# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
-# CONFIG_PKG_USING_RAPIDJSON is not set
-# CONFIG_PKG_USING_JSMN is not set
-# CONFIG_PKG_USING_AGILE_JSMN is not set
-# CONFIG_PKG_USING_PARSON is not set
-
-#
-# XML: Extensible Markup Language
-#
-# CONFIG_PKG_USING_SIMPLE_XML is not set
-# CONFIG_PKG_USING_EZXML is not set
-# CONFIG_PKG_USING_LUATOS_SOC is not set
-# CONFIG_PKG_USING_LUA is not set
-# CONFIG_PKG_USING_JERRYSCRIPT is not set
-# CONFIG_PKG_USING_MICROPYTHON is not set
-# CONFIG_PKG_USING_PIKASCRIPT is not set
-# CONFIG_PKG_USING_RTT_RUST is not set
-
-#
-# multimedia packages
-#
-
-#
-# LVGL: powerful and easy-to-use embedded GUI library
-#
-# CONFIG_PKG_USING_LVGL is not set
-# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
-# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
-# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set
-
-#
-# u8g2: a monochrome graphic library
-#
-# CONFIG_PKG_USING_U8G2_OFFICIAL is not set
-# CONFIG_PKG_USING_U8G2 is not set
-# CONFIG_PKG_USING_OPENMV is not set
-# CONFIG_PKG_USING_MUPDF is not set
-# CONFIG_PKG_USING_STEMWIN is not set
-# CONFIG_PKG_USING_WAVPLAYER is not set
-# CONFIG_PKG_USING_TJPGD is not set
-# CONFIG_PKG_USING_PDFGEN is not set
-# CONFIG_PKG_USING_HELIX is not set
-# CONFIG_PKG_USING_AZUREGUIX is not set
-# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
-# CONFIG_PKG_USING_NUEMWIN is not set
-# CONFIG_PKG_USING_MP3PLAYER is not set
-# CONFIG_PKG_USING_TINYJPEG is not set
-# CONFIG_PKG_USING_UGUI is not set
-
-#
-# PainterEngine: A cross-platform graphics application framework written in C language
-#
-# CONFIG_PKG_USING_PAINTERENGINE is not set
-# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
-# CONFIG_PKG_USING_MCURSES is not set
-# CONFIG_PKG_USING_TERMBOX is not set
-# CONFIG_PKG_USING_VT100 is not set
-# CONFIG_PKG_USING_QRCODE is not set
-# CONFIG_PKG_USING_GUIENGINE is not set
-# CONFIG_PKG_USING_PERSIMMON is not set
-
-#
-# tools packages
-#
-# CONFIG_PKG_USING_CMBACKTRACE is not set
-# CONFIG_PKG_USING_EASYFLASH is not set
-# CONFIG_PKG_USING_EASYLOGGER is not set
-# CONFIG_PKG_USING_SYSTEMVIEW is not set
-# CONFIG_PKG_USING_SEGGER_RTT is not set
-# CONFIG_PKG_USING_RDB is not set
-# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
-# CONFIG_PKG_USING_LOGMGR is not set
-# CONFIG_PKG_USING_ADBD is not set
-# CONFIG_PKG_USING_COREMARK is not set
-# CONFIG_PKG_USING_DHRYSTONE is not set
-# CONFIG_PKG_USING_MEMORYPERF is not set
-# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
-# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
-# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
-# CONFIG_PKG_USING_BS8116A is not set
-# CONFIG_PKG_USING_GPS_RMC is not set
-# CONFIG_PKG_USING_URLENCODE is not set
-# CONFIG_PKG_USING_UMCN is not set
-# CONFIG_PKG_USING_LWRB2RTT is not set
-# CONFIG_PKG_USING_CPU_USAGE is not set
-# CONFIG_PKG_USING_GBK2UTF8 is not set
-# CONFIG_PKG_USING_VCONSOLE is not set
-# CONFIG_PKG_USING_KDB is not set
-# CONFIG_PKG_USING_WAMR is not set
-# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
-# CONFIG_PKG_USING_LWLOG is not set
-# CONFIG_PKG_USING_ANV_TRACE is not set
-# CONFIG_PKG_USING_ANV_MEMLEAK is not set
-# CONFIG_PKG_USING_ANV_TESTSUIT is not set
-# CONFIG_PKG_USING_ANV_BENCH is not set
-# CONFIG_PKG_USING_DEVMEM is not set
-# CONFIG_PKG_USING_REGEX is not set
-# CONFIG_PKG_USING_MEM_SANDBOX is not set
-# CONFIG_PKG_USING_SOLAR_TERMS is not set
-# CONFIG_PKG_USING_GAN_ZHI is not set
-# CONFIG_PKG_USING_FDT is not set
-# CONFIG_PKG_USING_CBOX is not set
-# CONFIG_PKG_USING_SNOWFLAKE is not set
-# CONFIG_PKG_USING_HASH_MATCH is not set
-# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
-# CONFIG_PKG_USING_VOFA_PLUS is not set
-
-#
-# system packages
-#
-
-#
-# enhanced kernel services
-#
-# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
-# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
-# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
-
-#
-# acceleration: Assembly language or algorithmic acceleration packages
-#
-# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
-# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
-# CONFIG_PKG_USING_QFPLIB_M3 is not set
-
-#
-# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
-#
-# CONFIG_PKG_USING_CMSIS_5 is not set
-# CONFIG_PKG_USING_CMSIS_RTOS1 is not set
-# CONFIG_PKG_USING_CMSIS_RTOS2 is not set
-
-#
-# Micrium: Micrium software products porting for RT-Thread
-#
-# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
-# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
-# CONFIG_PKG_USING_UC_CRC is not set
-# CONFIG_PKG_USING_UC_CLK is not set
-# CONFIG_PKG_USING_UC_COMMON is not set
-# CONFIG_PKG_USING_UC_MODBUS is not set
-# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set
-# CONFIG_PKG_USING_CAIRO is not set
-# CONFIG_PKG_USING_PIXMAN is not set
-# CONFIG_PKG_USING_PARTITION is not set
-# CONFIG_PKG_USING_PERF_COUNTER is not set
-# CONFIG_PKG_USING_FLASHDB is not set
-# CONFIG_PKG_USING_SQLITE is not set
-# CONFIG_PKG_USING_RTI is not set
-# CONFIG_PKG_USING_DFS_YAFFS is not set
-# CONFIG_PKG_USING_LITTLEFS is not set
-# CONFIG_PKG_USING_DFS_JFFS2 is not set
-# CONFIG_PKG_USING_DFS_UFFS is not set
-# CONFIG_PKG_USING_LWEXT4 is not set
-# CONFIG_PKG_USING_THREAD_POOL is not set
-# CONFIG_PKG_USING_ROBOTS is not set
-# CONFIG_PKG_USING_EV is not set
-# CONFIG_PKG_USING_SYSWATCH is not set
-# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
-# CONFIG_PKG_USING_PLCCORE is not set
-# CONFIG_PKG_USING_RAMDISK is not set
-# CONFIG_PKG_USING_MININI is not set
-# CONFIG_PKG_USING_QBOOT is not set
-# CONFIG_PKG_USING_PPOOL is not set
-# CONFIG_PKG_USING_OPENAMP is not set
-# CONFIG_PKG_USING_LPM is not set
-# CONFIG_PKG_USING_TLSF is not set
-# CONFIG_PKG_USING_EVENT_RECORDER is not set
-# CONFIG_PKG_USING_ARM_2D is not set
-# CONFIG_PKG_USING_MCUBOOT is not set
-# CONFIG_PKG_USING_TINYUSB is not set
-# CONFIG_PKG_USING_CHERRYUSB is not set
-# CONFIG_PKG_USING_KMULTI_RTIMER is not set
-# CONFIG_PKG_USING_TFDB is not set
-# CONFIG_PKG_USING_QPC is not set
-# CONFIG_PKG_USING_AGILE_UPGRADE is not set
-
-#
-# peripheral libraries and drivers
-#
-
-#
-# sensors drivers
-#
-# CONFIG_PKG_USING_FINGERPRINT is not set
-# CONFIG_PKG_USING_LSM6DSM is not set
-# CONFIG_PKG_USING_LSM6DSL is not set
-# CONFIG_PKG_USING_LPS22HB is not set
-# CONFIG_PKG_USING_HTS221 is not set
-# CONFIG_PKG_USING_LSM303AGR is not set
-# CONFIG_PKG_USING_BME280 is not set
-# CONFIG_PKG_USING_BME680 is not set
-# CONFIG_PKG_USING_BMA400 is not set
-# CONFIG_PKG_USING_BMI160_BMX160 is not set
-# CONFIG_PKG_USING_SPL0601 is not set
-# CONFIG_PKG_USING_MS5805 is not set
-# CONFIG_PKG_USING_DA270 is not set
-# CONFIG_PKG_USING_DF220 is not set
-# CONFIG_PKG_USING_HSHCAL001 is not set
-# CONFIG_PKG_USING_BH1750 is not set
-# CONFIG_PKG_USING_MPU6XXX is not set
-# CONFIG_PKG_USING_AHT10 is not set
-# CONFIG_PKG_USING_AP3216C is not set
-# CONFIG_PKG_USING_TSL4531 is not set
-# CONFIG_PKG_USING_DS18B20 is not set
-# CONFIG_PKG_USING_DHT11 is not set
-# CONFIG_PKG_USING_DHTXX is not set
-# CONFIG_PKG_USING_GY271 is not set
-# CONFIG_PKG_USING_GP2Y10 is not set
-# CONFIG_PKG_USING_SGP30 is not set
-# CONFIG_PKG_USING_HDC1000 is not set
-# CONFIG_PKG_USING_BMP180 is not set
-# CONFIG_PKG_USING_BMP280 is not set
-# CONFIG_PKG_USING_SHTC1 is not set
-# CONFIG_PKG_USING_BMI088 is not set
-# CONFIG_PKG_USING_HMC5883 is not set
-# CONFIG_PKG_USING_MAX6675 is not set
-# CONFIG_PKG_USING_TMP1075 is not set
-# CONFIG_PKG_USING_SR04 is not set
-# CONFIG_PKG_USING_CCS811 is not set
-# CONFIG_PKG_USING_PMSXX is not set
-# CONFIG_PKG_USING_RT3020 is not set
-# CONFIG_PKG_USING_MLX90632 is not set
-# CONFIG_PKG_USING_MLX90393 is not set
-# CONFIG_PKG_USING_MLX90392 is not set
-# CONFIG_PKG_USING_MLX90397 is not set
-# CONFIG_PKG_USING_MS5611 is not set
-# CONFIG_PKG_USING_MAX31865 is not set
-# CONFIG_PKG_USING_VL53L0X is not set
-# CONFIG_PKG_USING_INA260 is not set
-# CONFIG_PKG_USING_MAX30102 is not set
-# CONFIG_PKG_USING_INA226 is not set
-# CONFIG_PKG_USING_LIS2DH12 is not set
-# CONFIG_PKG_USING_HS300X is not set
-# CONFIG_PKG_USING_ZMOD4410 is not set
-# CONFIG_PKG_USING_ISL29035 is not set
-# CONFIG_PKG_USING_MMC3680KJ is not set
-# CONFIG_PKG_USING_QMP6989 is not set
-# CONFIG_PKG_USING_BALANCE is not set
-# CONFIG_PKG_USING_SHT2X is not set
-# CONFIG_PKG_USING_SHT3X is not set
-# CONFIG_PKG_USING_AD7746 is not set
-# CONFIG_PKG_USING_ADT74XX is not set
-# CONFIG_PKG_USING_MAX17048 is not set
-
-#
-# touch drivers
-#
-# CONFIG_PKG_USING_GT9147 is not set
-# CONFIG_PKG_USING_GT1151 is not set
-# CONFIG_PKG_USING_GT917S is not set
-# CONFIG_PKG_USING_GT911 is not set
-# CONFIG_PKG_USING_FT6206 is not set
-# CONFIG_PKG_USING_FT5426 is not set
-# CONFIG_PKG_USING_FT6236 is not set
-# CONFIG_PKG_USING_XPT2046_TOUCH is not set
-# CONFIG_PKG_USING_REALTEK_AMEBA is not set
-# CONFIG_PKG_USING_AS7341 is not set
-# CONFIG_PKG_USING_STM32_SDIO is not set
-# CONFIG_PKG_USING_ESP_IDF is not set
-# CONFIG_PKG_USING_ICM20608 is not set
-# CONFIG_PKG_USING_BUTTON is not set
-# CONFIG_PKG_USING_PCF8574 is not set
-# CONFIG_PKG_USING_SX12XX is not set
-# CONFIG_PKG_USING_SIGNAL_LED is not set
-# CONFIG_PKG_USING_LEDBLINK is not set
-# CONFIG_PKG_USING_LITTLED is not set
-# CONFIG_PKG_USING_LKDGUI is not set
-# CONFIG_PKG_USING_NRF5X_SDK is not set
-# CONFIG_PKG_USING_NRFX is not set
-# CONFIG_PKG_USING_WM_LIBRARIES is not set
-
-#
-# Kendryte SDK
-#
-# CONFIG_PKG_USING_K210_SDK is not set
-# CONFIG_PKG_USING_KENDRYTE_SDK is not set
-# CONFIG_PKG_USING_INFRARED is not set
-# CONFIG_PKG_USING_MULTI_INFRARED is not set
-# CONFIG_PKG_USING_AGILE_BUTTON is not set
-# CONFIG_PKG_USING_AGILE_LED is not set
-# CONFIG_PKG_USING_AT24CXX is not set
-# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
-# CONFIG_PKG_USING_PCA9685 is not set
-# CONFIG_PKG_USING_I2C_TOOLS is not set
-# CONFIG_PKG_USING_NRF24L01 is not set
-# CONFIG_PKG_USING_RPLIDAR is not set
-# CONFIG_PKG_USING_AS608 is not set
-# CONFIG_PKG_USING_RC522 is not set
-# CONFIG_PKG_USING_WS2812B is not set
-# CONFIG_PKG_USING_EMBARC_BSP is not set
-# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
-# CONFIG_PKG_USING_MULTI_RTIMER is not set
-# CONFIG_PKG_USING_MAX7219 is not set
-# CONFIG_PKG_USING_BEEP is not set
-# CONFIG_PKG_USING_EASYBLINK is not set
-# CONFIG_PKG_USING_PMS_SERIES is not set
-# CONFIG_PKG_USING_CAN_YMODEM is not set
-# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
-# CONFIG_PKG_USING_QLED is not set
-# CONFIG_PKG_USING_PAJ7620 is not set
-# CONFIG_PKG_USING_AGILE_CONSOLE is not set
-# CONFIG_PKG_USING_LD3320 is not set
-# CONFIG_PKG_USING_WK2124 is not set
-# CONFIG_PKG_USING_LY68L6400 is not set
-# CONFIG_PKG_USING_DM9051 is not set
-# CONFIG_PKG_USING_SSD1306 is not set
-# CONFIG_PKG_USING_QKEY is not set
-# CONFIG_PKG_USING_RS485 is not set
-# CONFIG_PKG_USING_RS232 is not set
-# CONFIG_PKG_USING_NES is not set
-# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
-# CONFIG_PKG_USING_VDEVICE is not set
-# CONFIG_PKG_USING_SGM706 is not set
-# CONFIG_PKG_USING_STM32WB55_SDK is not set
-# CONFIG_PKG_USING_RDA58XX is not set
-# CONFIG_PKG_USING_LIBNFC is not set
-# CONFIG_PKG_USING_MFOC is not set
-# CONFIG_PKG_USING_TMC51XX is not set
-# CONFIG_PKG_USING_TCA9534 is not set
-# CONFIG_PKG_USING_KOBUKI is not set
-# CONFIG_PKG_USING_ROSSERIAL is not set
-# CONFIG_PKG_USING_MICRO_ROS is not set
-# CONFIG_PKG_USING_MCP23008 is not set
-# CONFIG_PKG_USING_BLUETRUM_SDK is not set
-# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
-# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
-# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
-# CONFIG_PKG_USING_BL_MCU_SDK is not set
-# CONFIG_PKG_USING_SOFT_SERIAL is not set
-# CONFIG_PKG_USING_MB85RS16 is not set
-# CONFIG_PKG_USING_CW2015 is not set
-# CONFIG_PKG_USING_RFM300 is not set
-# CONFIG_PKG_USING_IO_INPUT_FILTER is not set
-# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
-# CONFIG_PKG_USING_LRF_NV7LIDAR is not set
-
-#
-# AI packages
-#
-# CONFIG_PKG_USING_LIBANN is not set
-# CONFIG_PKG_USING_NNOM is not set
-# CONFIG_PKG_USING_ONNX_BACKEND is not set
-# CONFIG_PKG_USING_ONNX_PARSER is not set
-# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
-# CONFIG_PKG_USING_ELAPACK is not set
-# CONFIG_PKG_USING_ULAPACK is not set
-# CONFIG_PKG_USING_QUEST is not set
-# CONFIG_PKG_USING_NAXOS is not set
-
-#
-# Signal Processing and Control Algorithm Packages
-#
-# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
-# CONFIG_PKG_USING_UKAL is not set
-
-#
-# miscellaneous packages
-#
-
-#
-# project laboratory
-#
-
-#
-# samples: kernel and components samples
-#
-# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
-# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
-# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
-# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
-
-#
-# entertainment: terminal games and other interesting software packages
-#
-# CONFIG_PKG_USING_CMATRIX is not set
-# CONFIG_PKG_USING_SL is not set
-# CONFIG_PKG_USING_CAL is not set
-# CONFIG_PKG_USING_ACLOCK is not set
-# CONFIG_PKG_USING_THREES is not set
-# CONFIG_PKG_USING_2048 is not set
-# CONFIG_PKG_USING_SNAKE is not set
-# CONFIG_PKG_USING_TETRIS is not set
-# CONFIG_PKG_USING_DONUT is not set
-# CONFIG_PKG_USING_COWSAY is not set
-# CONFIG_PKG_USING_LIBCSV is not set
-# CONFIG_PKG_USING_OPTPARSE is not set
-# CONFIG_PKG_USING_FASTLZ is not set
-# CONFIG_PKG_USING_MINILZO is not set
-# CONFIG_PKG_USING_QUICKLZ is not set
-# CONFIG_PKG_USING_LZMA is not set
-# CONFIG_PKG_USING_MULTIBUTTON is not set
-# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
-# CONFIG_PKG_USING_CANFESTIVAL is not set
-# CONFIG_PKG_USING_ZLIB is not set
-# CONFIG_PKG_USING_MINIZIP is not set
-# CONFIG_PKG_USING_HEATSHRINK is not set
-# CONFIG_PKG_USING_DSTR is not set
-# CONFIG_PKG_USING_TINYFRAME is not set
-# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
-# CONFIG_PKG_USING_DIGITALCTRL is not set
-# CONFIG_PKG_USING_UPACKER is not set
-# CONFIG_PKG_USING_UPARAM is not set
-# CONFIG_PKG_USING_HELLO is not set
-# CONFIG_PKG_USING_VI is not set
-# CONFIG_PKG_USING_KI is not set
-# CONFIG_PKG_USING_ARMv7M_DWT is not set
-# CONFIG_PKG_USING_CRCLIB is not set
-# CONFIG_PKG_USING_LWGPS is not set
-# CONFIG_PKG_USING_STATE_MACHINE is not set
-# CONFIG_PKG_USING_DESIGN_PATTERN is not set
-# CONFIG_PKG_USING_CONTROLLER is not set
-# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set
-# CONFIG_PKG_USING_MFBD is not set
-# CONFIG_PKG_USING_SLCAN2RTT is not set
-# CONFIG_PKG_USING_SOEM is not set
-# CONFIG_PKG_USING_QPARAM is not set
-
-#
-# Arduino libraries
-#
-# CONFIG_PKG_USING_RTDUINO is not set
-
-#
-# Projects
-#
-# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
-# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
-# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
-
-#
-# Sensors
-#
-# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set
-# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
-# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set
-# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set
-# CONFIG_PKG_USING_SEEED_ITG3200 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set
-# CONFIG_PKG_USING_SEEED_MP503 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set
-
-#
-# Display
-#
-# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
-# CONFIG_PKG_USING_SEEED_TM1637 is not set
-
-#
-# Timing
-#
-# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set
-
-#
-# Data Processing
-#
-# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set
-# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set
-
-#
-# Data Storage
-#
-
-#
-# Communication
-#
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set
-
-#
-# Device Control
-#
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
-
-#
-# Other
-#
-
-#
-# Signal IO
-#
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set
-
-#
-# Uncategorized
-#
-
-#
-# Privated Packages of RealThread
-#
-# CONFIG_PKG_USING_CODEC is not set
-# CONFIG_PKG_USING_PLAYER is not set
-# CONFIG_PKG_USING_MPLAYER is not set
-# CONFIG_PKG_USING_PERSIMMON_SRC is not set
-# CONFIG_PKG_USING_JS_PERSIMMON is not set
-# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
-
-#
-# Network Utilities
-#
-# CONFIG_PKG_USING_WICED is not set
-# CONFIG_PKG_USING_CLOUDSDK is not set
-# CONFIG_PKG_USING_POWER_MANAGER is not set
-# CONFIG_PKG_USING_RT_OTA is not set
-# CONFIG_PKG_USING_RTINSIGHT is not set
-# CONFIG_PKG_USING_SMARTCONFIG is not set
-# CONFIG_PKG_USING_RTX is not set
-# CONFIG_RT_USING_TESTCASE is not set
-# CONFIG_PKG_USING_NGHTTP2 is not set
-# CONFIG_PKG_USING_AVS is not set
-# CONFIG_PKG_USING_ALI_LINKKIT is not set
-# CONFIG_PKG_USING_STS is not set
-# CONFIG_PKG_USING_DLMS is not set
-# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
-# CONFIG_PKG_USING_ZBAR is not set
-# CONFIG_PKG_USING_MCF is not set
-# CONFIG_PKG_USING_URPC is not set
-# CONFIG_PKG_USING_DCM is not set
-# CONFIG_PKG_USING_EMQ is not set
-# CONFIG_PKG_USING_CFGM is not set
-# CONFIG_PKG_USING_RT_CMSIS_DAP is not set
-# CONFIG_PKG_USING_SMODULE is not set
-# CONFIG_PKG_USING_SNFD is not set
-# CONFIG_PKG_USING_UDBD is not set
-# CONFIG_PKG_USING_BENCHMARK is not set
-# CONFIG_PKG_USING_UBJSON is not set
-# CONFIG_PKG_USING_DATATYPE is not set
-# CONFIG_PKG_USING_FASTFS is not set
-# CONFIG_PKG_USING_RIL is not set
-# CONFIG_PKG_USING_WATCH_DCM_SVC is not set
-# CONFIG_PKG_USING_WATCH_APP_FWK is not set
-# CONFIG_PKG_USING_GUI_TEST is not set
-# CONFIG_PKG_USING_PMEM is not set
-# CONFIG_PKG_USING_LWRDP is not set
-# CONFIG_PKG_USING_MASAN is not set
-# CONFIG_PKG_USING_BSDIFF_LIB is not set
-# CONFIG_PKG_USING_PRC_DIFF is not set
-
-#
-# RT-Thread Smart
-#
-# CONFIG_PKG_USING_UKERNEL is not set
-# CONFIG_PKG_USING_TRACE_AGENT is not set
-
-#
# Hardware Drivers Config
#
CONFIG_SOC_VEXPRESS_A9=y
diff --git a/bsp/qemu-vexpress-a9/drivers/board.c b/bsp/qemu-vexpress-a9/drivers/board.c
index 90ed26b394..8e5c36cf16 100644
--- a/bsp/qemu-vexpress-a9/drivers/board.c
+++ b/bsp/qemu-vexpress-a9/drivers/board.c
@@ -16,6 +16,7 @@
#include "board.h"
#include "drv_timer.h"
+#include "mm_aspace.h"
#include <mmu.h>
#ifdef RT_USING_SMART
@@ -49,8 +50,6 @@ void idle_wfi(void)
* This function will initialize board
*/
-rt_mmu_info mmu_info;
-
extern size_t MMUTable[];
#ifdef RT_USING_SMART
@@ -63,23 +62,23 @@ rt_region_t init_page_region = {
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
- rt_hw_mmu_map_init(&mmu_info, (void*)0xf0000000, 0x10000000, MMUTable, PV_OFFSET);
+ rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xf0000000, 0x10000000, MMUTable, PV_OFFSET);
rt_page_init(init_page_region);
- rt_hw_mmu_ioremap_init(&mmu_info, (void*)0xf0000000, 0x10000000);
+ rt_hw_mmu_ioremap_init(&rt_kernel_space, (void*)0xf0000000, 0x10000000);
- arch_kuser_init(&mmu_info, (void*)0xffff0000);
+ arch_kuser_init(&rt_kernel_space, (void*)0xffff0000);
#else
- rt_hw_mmu_map_init(&mmu_info, (void*)0x80000000, 0x10000000, MMUTable, 0);
- rt_hw_mmu_ioremap_init(&mmu_info, (void*)0x80000000, 0x10000000);
+ rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x80000000, 0x10000000, MMUTable, 0);
+ rt_hw_mmu_ioremap_init(&rt_kernel_space, (void*)0x80000000, 0x10000000);
#endif
- /* initialize hardware interrupt */
- rt_hw_interrupt_init();
-
/* initialize system heap */
rt_system_heap_init(HEAP_BEGIN, HEAP_END);
+ /* initialize hardware interrupt */
+ rt_hw_interrupt_init();
+
rt_components_board_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
diff --git a/bsp/qemu-vexpress-a9/drivers/board.h b/bsp/qemu-vexpress-a9/drivers/board.h
index 0f90314d2a..ee500a59c4 100644
--- a/bsp/qemu-vexpress-a9/drivers/board.h
+++ b/bsp/qemu-vexpress-a9/drivers/board.h
@@ -38,6 +38,4 @@ extern int __bss_end;
void rt_hw_board_init(void);
-extern rt_mmu_info mmu_info;
-
#endif
diff --git a/bsp/qemu-vexpress-a9/qemu-dbg.sh b/bsp/qemu-vexpress-a9/qemu-dbg.sh
index 44bc1ad967..2153eaad90 100755
--- a/bsp/qemu-vexpress-a9/qemu-dbg.sh
+++ b/bsp/qemu-vexpress-a9/qemu-dbg.sh
@@ -3,4 +3,4 @@ dd if=/dev/zero of=sd.bin bs=1024 count=65536
fi
-qemu-system-arm -M vexpress-a9 -kernel rtthread.elf -serial vc -serial vc -sd sd.bin -S -s \ No newline at end of file
+qemu-system-arm -M vexpress-a9 -smp cpus=2 -kernel rtthread.bin -nographic -sd sd.bin -S -s \ No newline at end of file
diff --git a/bsp/qemu-vexpress-a9/rtconfig.h b/bsp/qemu-vexpress-a9/rtconfig.h
index a646b13349..a71db46e9c 100644
--- a/bsp/qemu-vexpress-a9/rtconfig.h
+++ b/bsp/qemu-vexpress-a9/rtconfig.h
@@ -36,6 +36,7 @@
/* Memory Management */
+#define RT_PAGE_MAX_ORDER 11
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_MEMHEAP
@@ -115,6 +116,7 @@
#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
#define RT_USING_SERIAL
#define RT_USING_SERIAL_V1
+#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 256
#define RT_USING_I2C
#define RT_USING_I2C_BITOPS
@@ -181,130 +183,6 @@
/* RT-Thread Utestcases */
-/* RT-Thread online packages */
-
-/* IoT - internet of things */
-
-
-/* Wi-Fi */
-
-/* Marvell WiFi */
-
-
-/* Wiced WiFi */
-
-
-/* IoT Cloud */
-
-
-/* security packages */
-
-
-/* language packages */
-
-/* JSON: JavaScript Object Notation, a lightweight data-interchange format */
-
-
-/* XML: Extensible Markup Language */
-
-
-/* multimedia packages */
-
-/* LVGL: powerful and easy-to-use embedded GUI library */
-
-
-/* u8g2: a monochrome graphic library */
-
-
-/* PainterEngine: A cross-platform graphics application framework written in C language */
-
-
-/* tools packages */
-
-
-/* system packages */
-
-/* enhanced kernel services */
-
-
-/* acceleration: Assembly language or algorithmic acceleration packages */
-
-
-/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
-
-
-/* Micrium: Micrium software products porting for RT-Thread */
-
-
-/* peripheral libraries and drivers */
-
-/* sensors drivers */
-
-
-/* touch drivers */
-
-
-/* Kendryte SDK */
-
-
-/* AI packages */
-
-
-/* Signal Processing and Control Algorithm Packages */
-
-
-/* miscellaneous packages */
-
-/* project laboratory */
-
-/* samples: kernel and components samples */
-
-
-/* entertainment: terminal games and other interesting software packages */
-
-
-/* Arduino libraries */
-
-
-/* Projects */
-
-
-/* Sensors */
-
-
-/* Display */
-
-
-/* Timing */
-
-
-/* Data Processing */
-
-
-/* Data Storage */
-
-/* Communication */
-
-
-/* Device Control */
-
-
-/* Other */
-
-/* Signal IO */
-
-
-/* Uncategorized */
-
-/* Privated Packages of RealThread */
-
-
-/* Network Utilities */
-
-
-/* RT-Thread Smart */
-
-
/* Hardware Drivers Config */
#define SOC_VEXPRESS_A9
diff --git a/bsp/qemu-vexpress-a9/rtconfig.py b/bsp/qemu-vexpress-a9/rtconfig.py
index 9707400629..05a0eac377 100644
--- a/bsp/qemu-vexpress-a9/rtconfig.py
+++ b/bsp/qemu-vexpress-a9/rtconfig.py
@@ -53,7 +53,7 @@ if PLATFORM == 'gcc':
DEVICE = ' -march=armv7-a -mtune=cortex-a7 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing'
CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall'
- CFLAGS = DEVICE + CFPFLAGS + ' -Wall -std=gnu99'
+ CFLAGS = DEVICE + CFPFLAGS + ' -Wall -Wno-cpp -std=gnu99 -D_POSIX_SOURCE '
AFLAGS = DEVICE + ' -c' + AFPFLAGS + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T '+ LINK_SCRIPT + ' -lsupc++ -lgcc -static'
CPATH = ''
diff --git a/bsp/qemu-virt64-aarch64/.config b/bsp/qemu-virt64-aarch64/.config
index 26c0a30bee..a06efebe52 100644
--- a/bsp/qemu-virt64-aarch64/.config
+++ b/bsp/qemu-virt64-aarch64/.config
@@ -62,6 +62,7 @@ CONFIG_RT_USING_MESSAGEQUEUE=y
#
# Memory Management
#
+CONFIG_RT_PAGE_MAX_ORDER=11
CONFIG_RT_USING_MEMPOOL=y
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
@@ -278,632 +279,6 @@ CONFIG_RT_USING_POSIX_PIPE_SIZE=512
# RT-Thread Utestcases
#
# CONFIG_RT_USING_UTESTCASES is not set
-
-#
-# RT-Thread online packages
-#
-
-#
-# IoT - internet of things
-#
-# CONFIG_PKG_USING_LWIP is not set
-# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
-# CONFIG_PKG_USING_PAHOMQTT is not set
-# CONFIG_PKG_USING_UMQTT is not set
-# CONFIG_PKG_USING_WEBCLIENT is not set
-# CONFIG_PKG_USING_WEBNET is not set
-# CONFIG_PKG_USING_MONGOOSE is not set
-# CONFIG_PKG_USING_MYMQTT is not set
-# CONFIG_PKG_USING_KAWAII_MQTT is not set
-# CONFIG_PKG_USING_BC28_MQTT is not set
-# CONFIG_PKG_USING_WEBTERMINAL is not set
-# CONFIG_PKG_USING_LIBMODBUS is not set
-# CONFIG_PKG_USING_FREEMODBUS is not set
-# CONFIG_PKG_USING_NANOPB is not set
-
-#
-# Wi-Fi
-#
-
-#
-# Marvell WiFi
-#
-# CONFIG_PKG_USING_WLANMARVELL is not set
-
-#
-# Wiced WiFi
-#
-# CONFIG_PKG_USING_WLAN_WICED is not set
-# CONFIG_PKG_USING_RW007 is not set
-# CONFIG_PKG_USING_COAP is not set
-# CONFIG_PKG_USING_NOPOLL is not set
-# CONFIG_PKG_USING_NETUTILS is not set
-# CONFIG_PKG_USING_CMUX is not set
-# CONFIG_PKG_USING_PPP_DEVICE is not set
-# CONFIG_PKG_USING_AT_DEVICE is not set
-# CONFIG_PKG_USING_ATSRV_SOCKET is not set
-# CONFIG_PKG_USING_WIZNET is not set
-# CONFIG_PKG_USING_ZB_COORDINATOR is not set
-
-#
-# IoT Cloud
-#
-# CONFIG_PKG_USING_ONENET is not set
-# CONFIG_PKG_USING_GAGENT_CLOUD is not set
-# CONFIG_PKG_USING_ALI_IOTKIT is not set
-# CONFIG_PKG_USING_AZURE is not set
-# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
-# CONFIG_PKG_USING_JIOT-C-SDK is not set
-# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
-# CONFIG_PKG_USING_JOYLINK is not set
-# CONFIG_PKG_USING_EZ_IOT_OS is not set
-# CONFIG_PKG_USING_IOTSHARP_SDK is not set
-# CONFIG_PKG_USING_NIMBLE is not set
-# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set
-# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
-# CONFIG_PKG_USING_IPMSG is not set
-# CONFIG_PKG_USING_LSSDP is not set
-# CONFIG_PKG_USING_AIRKISS_OPEN is not set
-# CONFIG_PKG_USING_LIBRWS is not set
-# CONFIG_PKG_USING_TCPSERVER is not set
-# CONFIG_PKG_USING_PROTOBUF_C is not set
-# CONFIG_PKG_USING_DLT645 is not set
-# CONFIG_PKG_USING_QXWZ is not set
-# CONFIG_PKG_USING_SMTP_CLIENT is not set
-# CONFIG_PKG_USING_ABUP_FOTA is not set
-# CONFIG_PKG_USING_LIBCURL2RTT is not set
-# CONFIG_PKG_USING_CAPNP is not set
-# CONFIG_PKG_USING_AGILE_TELNET is not set
-# CONFIG_PKG_USING_NMEALIB is not set
-# CONFIG_PKG_USING_PDULIB is not set
-# CONFIG_PKG_USING_BTSTACK is not set
-# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
-# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
-# CONFIG_PKG_USING_MAVLINK is not set
-# CONFIG_PKG_USING_BSAL is not set
-# CONFIG_PKG_USING_AGILE_MODBUS is not set
-# CONFIG_PKG_USING_AGILE_FTP is not set
-# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
-# CONFIG_PKG_USING_RT_LINK_HW is not set
-# CONFIG_PKG_USING_LORA_PKT_FWD is not set
-# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set
-# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
-# CONFIG_PKG_USING_HM is not set
-# CONFIG_PKG_USING_SMALL_MODBUS is not set
-# CONFIG_PKG_USING_NET_SERVER is not set
-# CONFIG_PKG_USING_ZFTP is not set
-
-#
-# security packages
-#
-# CONFIG_PKG_USING_MBEDTLS is not set
-# CONFIG_PKG_USING_LIBSODIUM is not set
-# CONFIG_PKG_USING_LIBHYDROGEN is not set
-# CONFIG_PKG_USING_TINYCRYPT is not set
-# CONFIG_PKG_USING_TFM is not set
-# CONFIG_PKG_USING_YD_CRYPTO is not set
-
-#
-# language packages
-#
-
-#
-# JSON: JavaScript Object Notation, a lightweight data-interchange format
-#
-# CONFIG_PKG_USING_CJSON is not set
-# CONFIG_PKG_USING_LJSON is not set
-# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
-# CONFIG_PKG_USING_RAPIDJSON is not set
-# CONFIG_PKG_USING_JSMN is not set
-# CONFIG_PKG_USING_AGILE_JSMN is not set
-# CONFIG_PKG_USING_PARSON is not set
-
-#
-# XML: Extensible Markup Language
-#
-# CONFIG_PKG_USING_SIMPLE_XML is not set
-# CONFIG_PKG_USING_EZXML is not set
-# CONFIG_PKG_USING_LUATOS_SOC is not set
-# CONFIG_PKG_USING_LUA is not set
-# CONFIG_PKG_USING_JERRYSCRIPT is not set
-# CONFIG_PKG_USING_MICROPYTHON is not set
-# CONFIG_PKG_USING_PIKASCRIPT is not set
-# CONFIG_PKG_USING_RTT_RUST is not set
-
-#
-# multimedia packages
-#
-
-#
-# LVGL: powerful and easy-to-use embedded GUI library
-#
-# CONFIG_PKG_USING_LVGL is not set
-# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
-# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
-# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set
-
-#
-# u8g2: a monochrome graphic library
-#
-# CONFIG_PKG_USING_U8G2_OFFICIAL is not set
-# CONFIG_PKG_USING_U8G2 is not set
-# CONFIG_PKG_USING_OPENMV is not set
-# CONFIG_PKG_USING_MUPDF is not set
-# CONFIG_PKG_USING_STEMWIN is not set
-# CONFIG_PKG_USING_WAVPLAYER is not set
-# CONFIG_PKG_USING_TJPGD is not set
-# CONFIG_PKG_USING_PDFGEN is not set
-# CONFIG_PKG_USING_HELIX is not set
-# CONFIG_PKG_USING_AZUREGUIX is not set
-# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
-# CONFIG_PKG_USING_NUEMWIN is not set
-# CONFIG_PKG_USING_MP3PLAYER is not set
-# CONFIG_PKG_USING_TINYJPEG is not set
-# CONFIG_PKG_USING_UGUI is not set
-
-#
-# PainterEngine: A cross-platform graphics application framework written in C language
-#
-# CONFIG_PKG_USING_PAINTERENGINE is not set
-# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
-# CONFIG_PKG_USING_MCURSES is not set
-# CONFIG_PKG_USING_TERMBOX is not set
-# CONFIG_PKG_USING_VT100 is not set
-# CONFIG_PKG_USING_QRCODE is not set
-# CONFIG_PKG_USING_GUIENGINE is not set
-
-#
-# tools packages
-#
-# CONFIG_PKG_USING_CMBACKTRACE is not set
-# CONFIG_PKG_USING_EASYFLASH is not set
-# CONFIG_PKG_USING_EASYLOGGER is not set
-# CONFIG_PKG_USING_SYSTEMVIEW is not set
-# CONFIG_PKG_USING_SEGGER_RTT is not set
-# CONFIG_PKG_USING_RDB is not set
-# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
-# CONFIG_PKG_USING_ULOG_FILE is not set
-# CONFIG_PKG_USING_LOGMGR is not set
-# CONFIG_PKG_USING_ADBD is not set
-# CONFIG_PKG_USING_COREMARK is not set
-# CONFIG_PKG_USING_DHRYSTONE is not set
-# CONFIG_PKG_USING_MEMORYPERF is not set
-# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
-# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
-# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
-# CONFIG_PKG_USING_BS8116A is not set
-# CONFIG_PKG_USING_GPS_RMC is not set
-# CONFIG_PKG_USING_URLENCODE is not set
-# CONFIG_PKG_USING_UMCN is not set
-# CONFIG_PKG_USING_LWRB2RTT is not set
-# CONFIG_PKG_USING_CPU_USAGE is not set
-# CONFIG_PKG_USING_GBK2UTF8 is not set
-# CONFIG_PKG_USING_VCONSOLE is not set
-# CONFIG_PKG_USING_KDB is not set
-# CONFIG_PKG_USING_WAMR is not set
-# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
-# CONFIG_PKG_USING_LWLOG is not set
-# CONFIG_PKG_USING_ANV_TRACE is not set
-# CONFIG_PKG_USING_ANV_MEMLEAK is not set
-# CONFIG_PKG_USING_ANV_TESTSUIT is not set
-# CONFIG_PKG_USING_ANV_BENCH is not set
-# CONFIG_PKG_USING_DEVMEM is not set
-# CONFIG_PKG_USING_REGEX is not set
-# CONFIG_PKG_USING_MEM_SANDBOX is not set
-# CONFIG_PKG_USING_SOLAR_TERMS is not set
-# CONFIG_PKG_USING_GAN_ZHI is not set
-# CONFIG_PKG_USING_FDT is not set
-# CONFIG_PKG_USING_CBOX is not set
-# CONFIG_PKG_USING_SNOWFLAKE is not set
-# CONFIG_PKG_USING_HASH_MATCH is not set
-# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
-# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
-# CONFIG_PKG_USING_VOFA_PLUS is not set
-
-#
-# system packages
-#
-
-#
-# enhanced kernel services
-#
-# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
-# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
-# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
-
-#
-# acceleration: Assembly language or algorithmic acceleration packages
-#
-# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
-# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
-# CONFIG_PKG_USING_QFPLIB_M3 is not set
-
-#
-# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
-#
-# CONFIG_PKG_USING_CMSIS_5 is not set
-# CONFIG_PKG_USING_CMSIS_RTOS1 is not set
-# CONFIG_PKG_USING_CMSIS_RTOS2 is not set
-
-#
-# Micrium: Micrium software products porting for RT-Thread
-#
-# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
-# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
-# CONFIG_PKG_USING_UC_CRC is not set
-# CONFIG_PKG_USING_UC_CLK is not set
-# CONFIG_PKG_USING_UC_COMMON is not set
-# CONFIG_PKG_USING_UC_MODBUS is not set
-# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set
-# CONFIG_PKG_USING_CAIRO is not set
-# CONFIG_PKG_USING_PIXMAN is not set
-# CONFIG_PKG_USING_PARTITION is not set
-# CONFIG_PKG_USING_PERF_COUNTER is not set
-# CONFIG_PKG_USING_FLASHDB is not set
-# CONFIG_PKG_USING_SQLITE is not set
-# CONFIG_PKG_USING_RTI is not set
-# CONFIG_PKG_USING_DFS_YAFFS is not set
-# CONFIG_PKG_USING_LITTLEFS is not set
-# CONFIG_PKG_USING_DFS_JFFS2 is not set
-# CONFIG_PKG_USING_DFS_UFFS is not set
-# CONFIG_PKG_USING_LWEXT4 is not set
-# CONFIG_PKG_USING_THREAD_POOL is not set
-# CONFIG_PKG_USING_ROBOTS is not set
-# CONFIG_PKG_USING_EV is not set
-# CONFIG_PKG_USING_SYSWATCH is not set
-# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
-# CONFIG_PKG_USING_PLCCORE is not set
-# CONFIG_PKG_USING_RAMDISK is not set
-# CONFIG_PKG_USING_MININI is not set
-# CONFIG_PKG_USING_QBOOT is not set
-# CONFIG_PKG_USING_PPOOL is not set
-# CONFIG_PKG_USING_OPENAMP is not set
-# CONFIG_PKG_USING_LPM is not set
-# CONFIG_PKG_USING_TLSF is not set
-# CONFIG_PKG_USING_EVENT_RECORDER is not set
-# CONFIG_PKG_USING_ARM_2D is not set
-# CONFIG_PKG_USING_MCUBOOT is not set
-# CONFIG_PKG_USING_TINYUSB is not set
-# CONFIG_PKG_USING_CHERRYUSB is not set
-# CONFIG_PKG_USING_KMULTI_RTIMER is not set
-# CONFIG_PKG_USING_TFDB is not set
-# CONFIG_PKG_USING_QPC is not set
-# CONFIG_PKG_USING_AGILE_UPGRADE is not set
-
-#
-# peripheral libraries and drivers
-#
-# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
-# CONFIG_PKG_USING_REALTEK_AMEBA is not set
-# CONFIG_PKG_USING_SHT2X is not set
-# CONFIG_PKG_USING_SHT3X is not set
-# CONFIG_PKG_USING_ADT74XX is not set
-# CONFIG_PKG_USING_AS7341 is not set
-# CONFIG_PKG_USING_STM32_SDIO is not set
-# CONFIG_PKG_USING_ESP_IDF is not set
-# CONFIG_PKG_USING_ICM20608 is not set
-# CONFIG_PKG_USING_BUTTON is not set
-# CONFIG_PKG_USING_PCF8574 is not set
-# CONFIG_PKG_USING_SX12XX is not set
-# CONFIG_PKG_USING_SIGNAL_LED is not set
-# CONFIG_PKG_USING_LEDBLINK is not set
-# CONFIG_PKG_USING_LITTLED is not set
-# CONFIG_PKG_USING_LKDGUI is not set
-# CONFIG_PKG_USING_NRF5X_SDK is not set
-# CONFIG_PKG_USING_NRFX is not set
-# CONFIG_PKG_USING_WM_LIBRARIES is not set
-
-#
-# Kendryte SDK
-#
-# CONFIG_PKG_USING_K210_SDK is not set
-# CONFIG_PKG_USING_KENDRYTE_SDK is not set
-# CONFIG_PKG_USING_INFRARED is not set
-# CONFIG_PKG_USING_MULTI_INFRARED is not set
-# CONFIG_PKG_USING_AGILE_BUTTON is not set
-# CONFIG_PKG_USING_AGILE_LED is not set
-# CONFIG_PKG_USING_AT24CXX is not set
-# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
-# CONFIG_PKG_USING_AD7746 is not set
-# CONFIG_PKG_USING_PCA9685 is not set
-# CONFIG_PKG_USING_I2C_TOOLS is not set
-# CONFIG_PKG_USING_NRF24L01 is not set
-# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
-# CONFIG_PKG_USING_MAX17048 is not set
-# CONFIG_PKG_USING_RPLIDAR is not set
-# CONFIG_PKG_USING_AS608 is not set
-# CONFIG_PKG_USING_RC522 is not set
-# CONFIG_PKG_USING_WS2812B is not set
-# CONFIG_PKG_USING_EMBARC_BSP is not set
-# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
-# CONFIG_PKG_USING_MULTI_RTIMER is not set
-# CONFIG_PKG_USING_MAX7219 is not set
-# CONFIG_PKG_USING_BEEP is not set
-# CONFIG_PKG_USING_EASYBLINK is not set
-# CONFIG_PKG_USING_PMS_SERIES is not set
-# CONFIG_PKG_USING_CAN_YMODEM is not set
-# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
-# CONFIG_PKG_USING_QLED is not set
-# CONFIG_PKG_USING_PAJ7620 is not set
-# CONFIG_PKG_USING_AGILE_CONSOLE is not set
-# CONFIG_PKG_USING_LD3320 is not set
-# CONFIG_PKG_USING_WK2124 is not set
-# CONFIG_PKG_USING_LY68L6400 is not set
-# CONFIG_PKG_USING_DM9051 is not set
-# CONFIG_PKG_USING_SSD1306 is not set
-# CONFIG_PKG_USING_QKEY is not set
-# CONFIG_PKG_USING_RS485 is not set
-# CONFIG_PKG_USING_RS232 is not set
-# CONFIG_PKG_USING_NES is not set
-# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
-# CONFIG_PKG_USING_VDEVICE is not set
-# CONFIG_PKG_USING_SGM706 is not set
-# CONFIG_PKG_USING_STM32WB55_SDK is not set
-# CONFIG_PKG_USING_RDA58XX is not set
-# CONFIG_PKG_USING_LIBNFC is not set
-# CONFIG_PKG_USING_MFOC is not set
-# CONFIG_PKG_USING_TMC51XX is not set
-# CONFIG_PKG_USING_TCA9534 is not set
-# CONFIG_PKG_USING_KOBUKI is not set
-# CONFIG_PKG_USING_ROSSERIAL is not set
-# CONFIG_PKG_USING_MICRO_ROS is not set
-# CONFIG_PKG_USING_MCP23008 is not set
-# CONFIG_PKG_USING_BLUETRUM_SDK is not set
-# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
-# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
-# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
-# CONFIG_PKG_USING_BL_MCU_SDK is not set
-# CONFIG_PKG_USING_SOFT_SERIAL is not set
-# CONFIG_PKG_USING_MB85RS16 is not set
-# CONFIG_PKG_USING_CW2015 is not set
-# CONFIG_PKG_USING_RFM300 is not set
-# CONFIG_PKG_USING_IO_INPUT_FILTER is not set
-# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
-
-#
-# AI packages
-#
-# CONFIG_PKG_USING_LIBANN is not set
-# CONFIG_PKG_USING_NNOM is not set
-# CONFIG_PKG_USING_ONNX_BACKEND is not set
-# CONFIG_PKG_USING_ONNX_PARSER is not set
-# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
-# CONFIG_PKG_USING_ELAPACK is not set
-# CONFIG_PKG_USING_ULAPACK is not set
-# CONFIG_PKG_USING_QUEST is not set
-# CONFIG_PKG_USING_NAXOS is not set
-
-#
-# miscellaneous packages
-#
-
-#
-# project laboratory
-#
-
-#
-# samples: kernel and components samples
-#
-# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
-# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
-# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
-# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
-
-#
-# entertainment: terminal games and other interesting software packages
-#
-# CONFIG_PKG_USING_CMATRIX is not set
-# CONFIG_PKG_USING_SL is not set
-# CONFIG_PKG_USING_CAL is not set
-# CONFIG_PKG_USING_ACLOCK is not set
-# CONFIG_PKG_USING_THREES is not set
-# CONFIG_PKG_USING_2048 is not set
-# CONFIG_PKG_USING_SNAKE is not set
-# CONFIG_PKG_USING_TETRIS is not set
-# CONFIG_PKG_USING_DONUT is not set
-# CONFIG_PKG_USING_COWSAY is not set
-# CONFIG_PKG_USING_LIBCSV is not set
-# CONFIG_PKG_USING_OPTPARSE is not set
-# CONFIG_PKG_USING_FASTLZ is not set
-# CONFIG_PKG_USING_MINILZO is not set
-# CONFIG_PKG_USING_QUICKLZ is not set
-# CONFIG_PKG_USING_LZMA is not set
-# CONFIG_PKG_USING_MULTIBUTTON is not set
-# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
-# CONFIG_PKG_USING_CANFESTIVAL is not set
-# CONFIG_PKG_USING_ZLIB is not set
-# CONFIG_PKG_USING_MINIZIP is not set
-# CONFIG_PKG_USING_HEATSHRINK is not set
-# CONFIG_PKG_USING_DSTR is not set
-# CONFIG_PKG_USING_TINYFRAME is not set
-# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
-# CONFIG_PKG_USING_DIGITALCTRL is not set
-# CONFIG_PKG_USING_UPACKER is not set
-# CONFIG_PKG_USING_UPARAM is not set
-# CONFIG_PKG_USING_HELLO is not set
-# CONFIG_PKG_USING_VI is not set
-# CONFIG_PKG_USING_KI is not set
-# CONFIG_PKG_USING_ARMv7M_DWT is not set
-# CONFIG_PKG_USING_UKAL is not set
-# CONFIG_PKG_USING_CRCLIB is not set
-# CONFIG_PKG_USING_LWGPS is not set
-# CONFIG_PKG_USING_STATE_MACHINE is not set
-# CONFIG_PKG_USING_DESIGN_PATTERN is not set
-# CONFIG_PKG_USING_CONTROLLER is not set
-# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set
-# CONFIG_PKG_USING_MFBD is not set
-# CONFIG_PKG_USING_SLCAN2RTT is not set
-# CONFIG_PKG_USING_SOEM is not set
-# CONFIG_PKG_USING_QPARAM is not set
-
-#
-# Arduino libraries
-#
-# CONFIG_PKG_USING_RTDUINO is not set
-
-#
-# Projects
-#
-# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
-# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
-# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
-
-#
-# Sensors
-#
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
-# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
-# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set
-# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
-
-#
-# Display
-#
-# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
-
-#
-# Timing
-#
-# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set
-
-#
-# Data Processing
-#
-# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set
-# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set
-
-#
-# Data Storage
-#
-
-#
-# Communication
-#
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set
-
-#
-# Device Control
-#
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
-
-#
-# Other
-#
-
-#
-# Signal IO
-#
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set
-
-#
-# Uncategorized
-#
CONFIG_SOC_VIRT64_AARCH64=y
#
diff --git a/bsp/qemu-virt64-aarch64/drivers/board.c b/bsp/qemu-virt64-aarch64/drivers/board.c
index 07caa4d64b..823ac8c784 100644
--- a/bsp/qemu-virt64-aarch64/drivers/board.c
+++ b/bsp/qemu-virt64-aarch64/drivers/board.c
@@ -11,16 +11,17 @@
* add smp ipi init
*/
+#include "mm_aspace.h"
#include <rthw.h>
#include <rtthread.h>
#include <mmu.h>
#ifdef RT_USING_SMART
-#include <page.h>
#include <lwp_arch.h>
#endif
#include "board.h"
+#include <mm_page.h>
#include <interrupt.h>
#ifdef RT_USING_FDT
@@ -35,9 +36,13 @@ struct mem_desc platform_mem_desc[] = {
{KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, KERNEL_VADDR_START + PV_OFFSET, NORMAL_MEM}
};
#else
+
+#define PAGE_POOL_SIZE (2ul << 20)
+#define PHYMEM_END (0x48000000ul)
+
struct mem_desc platform_mem_desc[] =
{
- {0x40000000, 0x80000000 - 1, 0x40000000, NORMAL_MEM},
+ {0x40000000, PHYMEM_END - 1, 0x40000000, NORMAL_MEM},
// {PL031_RTC_BASE, PL031_RTC_BASE + 0x1000 - 1, PL031_RTC_BASE, DEVICE_MEM},
// {PL061_GPIO_BASE, PL061_GPIO_BASE + 0x1000 - 1, PL061_GPIO_BASE, DEVICE_MEM},
{PL011_UART0_BASE, PL011_UART0_BASE + ARCH_SECTION_SIZE - 1, PL011_UART0_BASE, DEVICE_MEM},
@@ -63,8 +68,6 @@ void idle_wfi(void)
* This function will initialize board
*/
-rt_mmu_info mmu_info;
-
extern size_t MMUTable[];
#ifdef RT_USING_SMART
@@ -72,30 +75,29 @@ rt_region_t init_page_region = {
PAGE_START,
PAGE_END,
};
+#else
+rt_region_t init_page_region = {
+ PHYMEM_END - PAGE_POOL_SIZE,
+ PHYMEM_END,
+};
#endif
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
- rt_page_init(init_page_region);
-
- rt_hw_mmu_setup(platform_mem_desc, platform_mem_desc_size);
-
- rt_hw_mmu_map_init(&mmu_info, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET);
-
- arch_kuser_init(&mmu_info, (void*)0xffffffffffff0000);
+ rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET);
#else
- rt_hw_mmu_setup(platform_mem_desc, platform_mem_desc_size);
- rt_hw_mmu_map_init(&mmu_info, (void*)0x80000000, 0x10000000, MMUTable, 0);
- rt_hw_mmu_ioremap_init(&mmu_info, (void*)0x80000000, 0x10000000);
+ rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x80000000, 0x10000000, MMUTable, 0);
#endif
-
- /* initialize hardware interrupt */
- rt_hw_interrupt_init();
+ rt_page_init(init_page_region);
+ rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
/* initialize system heap */
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
+ /* initialize hardware interrupt */
+ rt_hw_interrupt_init();
+
/* support debug feature before components init */
rt_hw_uart_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
diff --git a/bsp/qemu-virt64-aarch64/drivers/virt.h b/bsp/qemu-virt64-aarch64/drivers/virt.h
index 4e534b954d..10ea7a49c6 100644
--- a/bsp/qemu-virt64-aarch64/drivers/virt.h
+++ b/bsp/qemu-virt64-aarch64/drivers/virt.h
@@ -17,7 +17,6 @@
#include <mmu.h>
#include <ioremap.h>
-extern rt_mmu_info mmu_info;
#else
#define rt_ioremap(x, ...) (x)
#endif
diff --git a/bsp/qemu-virt64-aarch64/qemu-debug.sh b/bsp/qemu-virt64-aarch64/qemu-debug.sh
index 22591c7c0a..91f0cf7526 100644
--- a/bsp/qemu-virt64-aarch64/qemu-debug.sh
+++ b/bsp/qemu-virt64-aarch64/qemu-debug.sh
@@ -1,7 +1,7 @@
if [ ! -f "sd.bin" ]; then
dd if=/dev/zero of=sd.bin bs=1024 count=65536
fi
-qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -nographic \
+qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -m 128M -smp 4 -kernel rtthread.bin -nographic \
-drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 \
-netdev user,id=net0 -device virtio-net-device,netdev=net0,bus=virtio-mmio-bus.1 -s -S \
-device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0
diff --git a/bsp/qemu-virt64-aarch64/qemu.sh b/bsp/qemu-virt64-aarch64/qemu.sh
index 40eeabc551..f025e2c947 100755
--- a/bsp/qemu-virt64-aarch64/qemu.sh
+++ b/bsp/qemu-virt64-aarch64/qemu.sh
@@ -1,7 +1,7 @@
if [ ! -f "sd.bin" ]; then
dd if=/dev/zero of=sd.bin bs=1024 count=65536
fi
-qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -nographic \
+qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -m 128M -smp 4 -kernel rtthread.bin -nographic \
-drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 \
-netdev user,id=net0 -device virtio-net-device,netdev=net0,bus=virtio-mmio-bus.1 \
-device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0
diff --git a/bsp/qemu-virt64-aarch64/rtconfig.h b/bsp/qemu-virt64-aarch64/rtconfig.h
index c4d7927cb5..0bf60131ce 100644
--- a/bsp/qemu-virt64-aarch64/rtconfig.h
+++ b/bsp/qemu-virt64-aarch64/rtconfig.h
@@ -41,6 +41,7 @@
/* Memory Management */
+#define RT_PAGE_MAX_ORDER 11
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_MEMHEAP
@@ -169,114 +170,6 @@
/* RT-Thread Utestcases */
-
-/* RT-Thread online packages */
-
-/* IoT - internet of things */
-
-
-/* Wi-Fi */
-
-/* Marvell WiFi */
-
-
-/* Wiced WiFi */
-
-
-/* IoT Cloud */
-
-
-/* security packages */
-
-
-/* language packages */
-
-/* JSON: JavaScript Object Notation, a lightweight data-interchange format */
-
-
-/* XML: Extensible Markup Language */
-
-
-/* multimedia packages */
-
-/* LVGL: powerful and easy-to-use embedded GUI library */
-
-
-/* u8g2: a monochrome graphic library */
-
-
-/* PainterEngine: A cross-platform graphics application framework written in C language */
-
-
-/* tools packages */
-
-
-/* system packages */
-
-/* enhanced kernel services */
-
-
-/* acceleration: Assembly language or algorithmic acceleration packages */
-
-
-/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
-
-
-/* Micrium: Micrium software products porting for RT-Thread */
-
-
-/* peripheral libraries and drivers */
-
-
-/* Kendryte SDK */
-
-
-/* AI packages */
-
-
-/* miscellaneous packages */
-
-/* project laboratory */
-
-/* samples: kernel and components samples */
-
-
-/* entertainment: terminal games and other interesting software packages */
-
-
-/* Arduino libraries */
-
-
-/* Projects */
-
-
-/* Sensors */
-
-
-/* Display */
-
-
-/* Timing */
-
-
-/* Data Processing */
-
-
-/* Data Storage */
-
-/* Communication */
-
-
-/* Device Control */
-
-
-/* Other */
-
-/* Signal IO */
-
-
-/* Uncategorized */
-
#define SOC_VIRT64_AARCH64
/* AARCH64 qemu virt64 configs */
diff --git a/bsp/qemu-virt64-riscv/.config b/bsp/qemu-virt64-riscv/.config
index 2aba51bf73..2a952fba52 100644
--- a/bsp/qemu-virt64-riscv/.config
+++ b/bsp/qemu-virt64-riscv/.config
@@ -6,7 +6,7 @@
#
# RT-Thread Kernel
#
-CONFIG_RT_NAME_MAX=20
+CONFIG_RT_NAME_MAX=24
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
# CONFIG_RT_USING_SMART is not set
# CONFIG_RT_USING_SMP is not set
@@ -60,6 +60,7 @@ CONFIG_RT_USING_SIGNALS=y
#
# Memory Management
#
+CONFIG_RT_PAGE_MAX_ORDER=11
CONFIG_RT_USING_MEMPOOL=y
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
@@ -90,7 +91,6 @@ CONFIG_RT_USING_CACHE=y
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
# CONFIG_RT_USING_CPU_FFS is not set
CONFIG_ARCH_MM_MMU=y
-# CONFIG_RT_USING_USERSPACE is not set
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_RISCV64=y
@@ -154,7 +154,6 @@ CONFIG_RT_USING_DFS_ROMFS=y
# CONFIG_RT_USING_DFS_TMPFS is not set
# CONFIG_RT_USING_DFS_NFS is not set
# CONFIG_RT_USING_FAL is not set
-# CONFIG_RT_USING_LWP is not set
#
# Device Drivers
@@ -206,7 +205,8 @@ CONFIG_RT_USING_VIRTIO10=y
# CONFIG_RT_USING_VIRTIO_MMIO_ALIGN is not set
CONFIG_RT_USING_VIRTIO_BLK=y
CONFIG_RT_USING_VIRTIO_NET=y
-# CONFIG_RT_USING_VIRTIO_CONSOLE is not set
+CONFIG_RT_USING_VIRTIO_CONSOLE=y
+CONFIG_RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR=4
# CONFIG_RT_USING_VIRTIO_GPU is not set
# CONFIG_RT_USING_VIRTIO_INPUT is not set
@@ -353,645 +353,20 @@ CONFIG_UTEST_THR_PRIORITY=20
# CONFIG_RT_USING_UTESTCASES is not set
#
-# RT-Thread online packages
-#
-
-#
-# IoT - internet of things
-#
-# CONFIG_PKG_USING_LWIP is not set
-# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
-# CONFIG_PKG_USING_PAHOMQTT is not set
-# CONFIG_PKG_USING_UMQTT is not set
-# CONFIG_PKG_USING_WEBCLIENT is not set
-# CONFIG_PKG_USING_WEBNET is not set
-# CONFIG_PKG_USING_MONGOOSE is not set
-# CONFIG_PKG_USING_MYMQTT is not set
-# CONFIG_PKG_USING_KAWAII_MQTT is not set
-# CONFIG_PKG_USING_BC28_MQTT is not set
-# CONFIG_PKG_USING_WEBTERMINAL is not set
-# CONFIG_PKG_USING_LIBMODBUS is not set
-# CONFIG_PKG_USING_FREEMODBUS is not set
-# CONFIG_PKG_USING_NANOPB is not set
-
-#
-# Wi-Fi
-#
-
-#
-# Marvell WiFi
-#
-# CONFIG_PKG_USING_WLANMARVELL is not set
-
-#
-# Wiced WiFi
-#
-# CONFIG_PKG_USING_WLAN_WICED is not set
-# CONFIG_PKG_USING_RW007 is not set
-# CONFIG_PKG_USING_COAP is not set
-# CONFIG_PKG_USING_NOPOLL is not set
-# CONFIG_PKG_USING_NETUTILS is not set
-# CONFIG_PKG_USING_CMUX is not set
-# CONFIG_PKG_USING_PPP_DEVICE is not set
-# CONFIG_PKG_USING_AT_DEVICE is not set
-# CONFIG_PKG_USING_ATSRV_SOCKET is not set
-# CONFIG_PKG_USING_WIZNET is not set
-# CONFIG_PKG_USING_ZB_COORDINATOR is not set
-
-#
-# IoT Cloud
-#
-# CONFIG_PKG_USING_ONENET is not set
-# CONFIG_PKG_USING_GAGENT_CLOUD is not set
-# CONFIG_PKG_USING_ALI_IOTKIT is not set
-# CONFIG_PKG_USING_AZURE is not set
-# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
-# CONFIG_PKG_USING_JIOT-C-SDK is not set
-# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
-# CONFIG_PKG_USING_JOYLINK is not set
-# CONFIG_PKG_USING_EZ_IOT_OS is not set
-# CONFIG_PKG_USING_IOTSHARP_SDK is not set
-# CONFIG_PKG_USING_NIMBLE is not set
-# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set
-# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
-# CONFIG_PKG_USING_IPMSG is not set
-# CONFIG_PKG_USING_LSSDP is not set
-# CONFIG_PKG_USING_AIRKISS_OPEN is not set
-# CONFIG_PKG_USING_LIBRWS is not set
-# CONFIG_PKG_USING_TCPSERVER is not set
-# CONFIG_PKG_USING_PROTOBUF_C is not set
-# CONFIG_PKG_USING_DLT645 is not set
-# CONFIG_PKG_USING_QXWZ is not set
-# CONFIG_PKG_USING_SMTP_CLIENT is not set
-# CONFIG_PKG_USING_ABUP_FOTA is not set
-# CONFIG_PKG_USING_LIBCURL2RTT is not set
-# CONFIG_PKG_USING_CAPNP is not set
-# CONFIG_PKG_USING_AGILE_TELNET is not set
-# CONFIG_PKG_USING_NMEALIB is not set
-# CONFIG_PKG_USING_PDULIB is not set
-# CONFIG_PKG_USING_BTSTACK is not set
-# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
-# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
-# CONFIG_PKG_USING_MAVLINK is not set
-# CONFIG_PKG_USING_BSAL is not set
-# CONFIG_PKG_USING_AGILE_MODBUS is not set
-# CONFIG_PKG_USING_AGILE_FTP is not set
-# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
-# CONFIG_PKG_USING_RT_LINK_HW is not set
-# CONFIG_PKG_USING_LORA_PKT_FWD is not set
-# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set
-# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
-# CONFIG_PKG_USING_HM is not set
-# CONFIG_PKG_USING_SMALL_MODBUS is not set
-# CONFIG_PKG_USING_NET_SERVER is not set
-# CONFIG_PKG_USING_ZFTP is not set
-
-#
-# security packages
-#
-# CONFIG_PKG_USING_MBEDTLS is not set
-# CONFIG_PKG_USING_LIBSODIUM is not set
-# CONFIG_PKG_USING_LIBHYDROGEN is not set
-# CONFIG_PKG_USING_TINYCRYPT is not set
-# CONFIG_PKG_USING_TFM is not set
-# CONFIG_PKG_USING_YD_CRYPTO is not set
-
-#
-# language packages
-#
-
-#
-# JSON: JavaScript Object Notation, a lightweight data-interchange format
-#
-# CONFIG_PKG_USING_CJSON is not set
-# CONFIG_PKG_USING_LJSON is not set
-# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
-# CONFIG_PKG_USING_RAPIDJSON is not set
-# CONFIG_PKG_USING_JSMN is not set
-# CONFIG_PKG_USING_AGILE_JSMN is not set
-# CONFIG_PKG_USING_PARSON is not set
-
-#
-# XML: Extensible Markup Language
-#
-# CONFIG_PKG_USING_SIMPLE_XML is not set
-# CONFIG_PKG_USING_EZXML is not set
-# CONFIG_PKG_USING_LUATOS_SOC is not set
-# CONFIG_PKG_USING_LUA is not set
-# CONFIG_PKG_USING_JERRYSCRIPT is not set
-# CONFIG_PKG_USING_MICROPYTHON is not set
-# CONFIG_PKG_USING_PIKASCRIPT is not set
-# CONFIG_PKG_USING_RTT_RUST is not set
-
-#
-# multimedia packages
-#
-
-#
-# LVGL: powerful and easy-to-use embedded GUI library
-#
-# CONFIG_PKG_USING_LVGL is not set
-# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
-# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
-# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set
-
-#
-# u8g2: a monochrome graphic library
-#
-# CONFIG_PKG_USING_U8G2_OFFICIAL is not set
-# CONFIG_PKG_USING_U8G2 is not set
-# CONFIG_PKG_USING_OPENMV is not set
-# CONFIG_PKG_USING_MUPDF is not set
-# CONFIG_PKG_USING_STEMWIN is not set
-# CONFIG_PKG_USING_WAVPLAYER is not set
-# CONFIG_PKG_USING_TJPGD is not set
-# CONFIG_PKG_USING_PDFGEN is not set
-# CONFIG_PKG_USING_HELIX is not set
-# CONFIG_PKG_USING_AZUREGUIX is not set
-# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
-# CONFIG_PKG_USING_NUEMWIN is not set
-# CONFIG_PKG_USING_MP3PLAYER is not set
-# CONFIG_PKG_USING_TINYJPEG is not set
-# CONFIG_PKG_USING_UGUI is not set
-
-#
-# PainterEngine: A cross-platform graphics application framework written in C language
-#
-# CONFIG_PKG_USING_PAINTERENGINE is not set
-# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
-# CONFIG_PKG_USING_MCURSES is not set
-# CONFIG_PKG_USING_TERMBOX is not set
-# CONFIG_PKG_USING_VT100 is not set
-# CONFIG_PKG_USING_QRCODE is not set
-# CONFIG_PKG_USING_GUIENGINE is not set
-
-#
-# tools packages
-#
-# CONFIG_PKG_USING_CMBACKTRACE is not set
-# CONFIG_PKG_USING_EASYFLASH is not set
-# CONFIG_PKG_USING_EASYLOGGER is not set
-# CONFIG_PKG_USING_SYSTEMVIEW is not set
-# CONFIG_PKG_USING_SEGGER_RTT is not set
-# CONFIG_PKG_USING_RDB is not set
-# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
-# CONFIG_PKG_USING_ULOG_FILE is not set
-# CONFIG_PKG_USING_LOGMGR is not set
-# CONFIG_PKG_USING_ADBD is not set
-# CONFIG_PKG_USING_COREMARK is not set
-# CONFIG_PKG_USING_DHRYSTONE is not set
-# CONFIG_PKG_USING_MEMORYPERF is not set
-# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
-# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
-# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
-# CONFIG_PKG_USING_BS8116A is not set
-# CONFIG_PKG_USING_GPS_RMC is not set
-# CONFIG_PKG_USING_URLENCODE is not set
-# CONFIG_PKG_USING_UMCN is not set
-# CONFIG_PKG_USING_LWRB2RTT is not set
-# CONFIG_PKG_USING_CPU_USAGE is not set
-# CONFIG_PKG_USING_GBK2UTF8 is not set
-# CONFIG_PKG_USING_VCONSOLE is not set
-# CONFIG_PKG_USING_KDB is not set
-# CONFIG_PKG_USING_WAMR is not set
-# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
-# CONFIG_PKG_USING_LWLOG is not set
-# CONFIG_PKG_USING_ANV_TRACE is not set
-# CONFIG_PKG_USING_ANV_MEMLEAK is not set
-# CONFIG_PKG_USING_ANV_TESTSUIT is not set
-# CONFIG_PKG_USING_ANV_BENCH is not set
-# CONFIG_PKG_USING_DEVMEM is not set
-# CONFIG_PKG_USING_REGEX is not set
-# CONFIG_PKG_USING_MEM_SANDBOX is not set
-# CONFIG_PKG_USING_SOLAR_TERMS is not set
-# CONFIG_PKG_USING_GAN_ZHI is not set
-# CONFIG_PKG_USING_FDT is not set
-# CONFIG_PKG_USING_CBOX is not set
-# CONFIG_PKG_USING_SNOWFLAKE is not set
-# CONFIG_PKG_USING_HASH_MATCH is not set
-# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
-# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
-# CONFIG_PKG_USING_VOFA_PLUS is not set
-
-#
-# system packages
-#
-
-#
-# enhanced kernel services
-#
-# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
-# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
-# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
-
-#
-# acceleration: Assembly language or algorithmic acceleration packages
-#
-# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
-# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
-# CONFIG_PKG_USING_QFPLIB_M3 is not set
-
-#
-# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
-#
-# CONFIG_PKG_USING_CMSIS_5 is not set
-# CONFIG_PKG_USING_CMSIS_RTOS1 is not set
-# CONFIG_PKG_USING_CMSIS_RTOS2 is not set
-
-#
-# Micrium: Micrium software products porting for RT-Thread
-#
-# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
-# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
-# CONFIG_PKG_USING_UC_CRC is not set
-# CONFIG_PKG_USING_UC_CLK is not set
-# CONFIG_PKG_USING_UC_COMMON is not set
-# CONFIG_PKG_USING_UC_MODBUS is not set
-# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set
-# CONFIG_PKG_USING_CAIRO is not set
-# CONFIG_PKG_USING_PIXMAN is not set
-# CONFIG_PKG_USING_PARTITION is not set
-# CONFIG_PKG_USING_PERF_COUNTER is not set
-# CONFIG_PKG_USING_FLASHDB is not set
-# CONFIG_PKG_USING_SQLITE is not set
-# CONFIG_PKG_USING_RTI is not set
-# CONFIG_PKG_USING_DFS_YAFFS is not set
-# CONFIG_PKG_USING_LITTLEFS is not set
-# CONFIG_PKG_USING_DFS_JFFS2 is not set
-# CONFIG_PKG_USING_DFS_UFFS is not set
-# CONFIG_PKG_USING_LWEXT4 is not set
-# CONFIG_PKG_USING_THREAD_POOL is not set
-# CONFIG_PKG_USING_ROBOTS is not set
-# CONFIG_PKG_USING_EV is not set
-# CONFIG_PKG_USING_SYSWATCH is not set
-# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
-# CONFIG_PKG_USING_PLCCORE is not set
-# CONFIG_PKG_USING_RAMDISK is not set
-# CONFIG_PKG_USING_MININI is not set
-# CONFIG_PKG_USING_QBOOT is not set
-# CONFIG_PKG_USING_PPOOL is not set
-# CONFIG_PKG_USING_OPENAMP is not set
-# CONFIG_PKG_USING_LPM is not set
-# CONFIG_PKG_USING_TLSF is not set
-# CONFIG_PKG_USING_EVENT_RECORDER is not set
-# CONFIG_PKG_USING_ARM_2D is not set
-# CONFIG_PKG_USING_MCUBOOT is not set
-# CONFIG_PKG_USING_TINYUSB is not set
-# CONFIG_PKG_USING_CHERRYUSB is not set
-# CONFIG_PKG_USING_KMULTI_RTIMER is not set
-# CONFIG_PKG_USING_TFDB is not set
-# CONFIG_PKG_USING_QPC is not set
-# CONFIG_PKG_USING_AGILE_UPGRADE is not set
-
-#
-# peripheral libraries and drivers
-#
-# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
-# CONFIG_PKG_USING_REALTEK_AMEBA is not set
-# CONFIG_PKG_USING_SHT2X is not set
-# CONFIG_PKG_USING_SHT3X is not set
-# CONFIG_PKG_USING_ADT74XX is not set
-# CONFIG_PKG_USING_AS7341 is not set
-# CONFIG_PKG_USING_STM32_SDIO is not set
-# CONFIG_PKG_USING_ESP_IDF is not set
-# CONFIG_PKG_USING_ICM20608 is not set
-# CONFIG_PKG_USING_BUTTON is not set
-# CONFIG_PKG_USING_PCF8574 is not set
-# CONFIG_PKG_USING_SX12XX is not set
-# CONFIG_PKG_USING_SIGNAL_LED is not set
-# CONFIG_PKG_USING_LEDBLINK is not set
-# CONFIG_PKG_USING_LITTLED is not set
-# CONFIG_PKG_USING_LKDGUI is not set
-# CONFIG_PKG_USING_NRF5X_SDK is not set
-# CONFIG_PKG_USING_NRFX is not set
-# CONFIG_PKG_USING_WM_LIBRARIES is not set
-
-#
-# Kendryte SDK
-#
-# CONFIG_PKG_USING_K210_SDK is not set
-# CONFIG_PKG_USING_KENDRYTE_SDK is not set
-# CONFIG_PKG_USING_INFRARED is not set
-# CONFIG_PKG_USING_MULTI_INFRARED is not set
-# CONFIG_PKG_USING_AGILE_BUTTON is not set
-# CONFIG_PKG_USING_AGILE_LED is not set
-# CONFIG_PKG_USING_AT24CXX is not set
-# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
-# CONFIG_PKG_USING_AD7746 is not set
-# CONFIG_PKG_USING_PCA9685 is not set
-# CONFIG_PKG_USING_I2C_TOOLS is not set
-# CONFIG_PKG_USING_NRF24L01 is not set
-# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
-# CONFIG_PKG_USING_MAX17048 is not set
-# CONFIG_PKG_USING_RPLIDAR is not set
-# CONFIG_PKG_USING_AS608 is not set
-# CONFIG_PKG_USING_RC522 is not set
-# CONFIG_PKG_USING_WS2812B is not set
-# CONFIG_PKG_USING_EMBARC_BSP is not set
-# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
-# CONFIG_PKG_USING_MULTI_RTIMER is not set
-# CONFIG_PKG_USING_MAX7219 is not set
-# CONFIG_PKG_USING_BEEP is not set
-# CONFIG_PKG_USING_EASYBLINK is not set
-# CONFIG_PKG_USING_PMS_SERIES is not set
-# CONFIG_PKG_USING_NUCLEI_SDK is not set
-# CONFIG_PKG_USING_CAN_YMODEM is not set
-# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
-# CONFIG_PKG_USING_QLED is not set
-# CONFIG_PKG_USING_PAJ7620 is not set
-# CONFIG_PKG_USING_AGILE_CONSOLE is not set
-# CONFIG_PKG_USING_LD3320 is not set
-# CONFIG_PKG_USING_WK2124 is not set
-# CONFIG_PKG_USING_LY68L6400 is not set
-# CONFIG_PKG_USING_DM9051 is not set
-# CONFIG_PKG_USING_SSD1306 is not set
-# CONFIG_PKG_USING_QKEY is not set
-# CONFIG_PKG_USING_RS485 is not set
-# CONFIG_PKG_USING_RS232 is not set
-# CONFIG_PKG_USING_NES is not set
-# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
-# CONFIG_PKG_USING_VDEVICE is not set
-# CONFIG_PKG_USING_SGM706 is not set
-# CONFIG_PKG_USING_STM32WB55_SDK is not set
-# CONFIG_PKG_USING_RDA58XX is not set
-# CONFIG_PKG_USING_LIBNFC is not set
-# CONFIG_PKG_USING_MFOC is not set
-# CONFIG_PKG_USING_TMC51XX is not set
-# CONFIG_PKG_USING_TCA9534 is not set
-# CONFIG_PKG_USING_KOBUKI is not set
-# CONFIG_PKG_USING_ROSSERIAL is not set
-# CONFIG_PKG_USING_MICRO_ROS is not set
-# CONFIG_PKG_USING_MCP23008 is not set
-# CONFIG_PKG_USING_BLUETRUM_SDK is not set
-# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
-# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
-# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
-# CONFIG_PKG_USING_BL_MCU_SDK is not set
-# CONFIG_PKG_USING_SOFT_SERIAL is not set
-# CONFIG_PKG_USING_MB85RS16 is not set
-# CONFIG_PKG_USING_CW2015 is not set
-# CONFIG_PKG_USING_RFM300 is not set
-# CONFIG_PKG_USING_IO_INPUT_FILTER is not set
-# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
-
-#
-# AI packages
-#
-# CONFIG_PKG_USING_LIBANN is not set
-# CONFIG_PKG_USING_NNOM is not set
-# CONFIG_PKG_USING_ONNX_BACKEND is not set
-# CONFIG_PKG_USING_ONNX_PARSER is not set
-# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
-# CONFIG_PKG_USING_ELAPACK is not set
-# CONFIG_PKG_USING_ULAPACK is not set
-# CONFIG_PKG_USING_QUEST is not set
-# CONFIG_PKG_USING_NAXOS is not set
-
-#
-# miscellaneous packages
-#
-
-#
-# project laboratory
-#
-
-#
-# samples: kernel and components samples
-#
-# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
-# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
-# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
-# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
-
-#
-# entertainment: terminal games and other interesting software packages
-#
-# CONFIG_PKG_USING_CMATRIX is not set
-# CONFIG_PKG_USING_SL is not set
-# CONFIG_PKG_USING_CAL is not set
-# CONFIG_PKG_USING_ACLOCK is not set
-# CONFIG_PKG_USING_THREES is not set
-# CONFIG_PKG_USING_2048 is not set
-# CONFIG_PKG_USING_SNAKE is not set
-# CONFIG_PKG_USING_TETRIS is not set
-# CONFIG_PKG_USING_DONUT is not set
-# CONFIG_PKG_USING_COWSAY is not set
-# CONFIG_PKG_USING_LIBCSV is not set
-# CONFIG_PKG_USING_OPTPARSE is not set
-# CONFIG_PKG_USING_FASTLZ is not set
-# CONFIG_PKG_USING_MINILZO is not set
-# CONFIG_PKG_USING_QUICKLZ is not set
-# CONFIG_PKG_USING_LZMA is not set
-# CONFIG_PKG_USING_MULTIBUTTON is not set
-# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
-# CONFIG_PKG_USING_CANFESTIVAL is not set
-# CONFIG_PKG_USING_ZLIB is not set
-# CONFIG_PKG_USING_MINIZIP is not set
-# CONFIG_PKG_USING_HEATSHRINK is not set
-# CONFIG_PKG_USING_DSTR is not set
-# CONFIG_PKG_USING_TINYFRAME is not set
-# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
-# CONFIG_PKG_USING_DIGITALCTRL is not set
-# CONFIG_PKG_USING_UPACKER is not set
-# CONFIG_PKG_USING_UPARAM is not set
-# CONFIG_PKG_USING_HELLO is not set
-# CONFIG_PKG_USING_VI is not set
-# CONFIG_PKG_USING_KI is not set
-# CONFIG_PKG_USING_ARMv7M_DWT is not set
-# CONFIG_PKG_USING_UKAL is not set
-# CONFIG_PKG_USING_CRCLIB is not set
-# CONFIG_PKG_USING_LWGPS is not set
-# CONFIG_PKG_USING_STATE_MACHINE is not set
-# CONFIG_PKG_USING_DESIGN_PATTERN is not set
-# CONFIG_PKG_USING_CONTROLLER is not set
-# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set
-# CONFIG_PKG_USING_MFBD is not set
-# CONFIG_PKG_USING_SLCAN2RTT is not set
-# CONFIG_PKG_USING_SOEM is not set
-# CONFIG_PKG_USING_QPARAM is not set
-
-#
-# Arduino libraries
-#
-# CONFIG_PKG_USING_RTDUINO is not set
-
-#
-# Projects
-#
-# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
-# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
-# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
-
-#
-# Sensors
-#
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
-# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
-# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set
-# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
-
-#
-# Display
-#
-# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
-
-#
-# Timing
-#
-# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set
-
-#
-# Data Processing
-#
-# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set
-# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set
-
-#
-# Data Storage
-#
-
-#
-# Communication
-#
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set
-
-#
-# Device Control
-#
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
-
-#
-# Other
-#
-
-#
-# Signal IO
-#
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set
-
-#
-# Uncategorized
-#
-
-#
# RISC-V QEMU virt64 configs
#
CONFIG_RISCV_S_MODE=y
CONFIG_BSP_USING_VIRTIO_BLK=y
CONFIG_BSP_USING_VIRTIO_NET=y
-# CONFIG_BSP_USING_VIRTIO_CONSOLE is not set
+CONFIG_BSP_USING_VIRTIO_CONSOLE=y
# CONFIG_BSP_USING_VIRTIO_GPU is not set
# CONFIG_BSP_USING_VIRTIO_INPUT is not set
# CONFIG_BSP_USING_UART1 is not set
CONFIG_BOARD_QEMU_VIRT_RV64=y
CONFIG_ENABLE_FPU=y
# CONFIG_ENABLE_VECTOR is not set
+# CONFIG_ARCH_VECTOR_VLEN_128 is not set
+# CONFIG_ARCH_VECTOR_VLEN_256 is not set
# CONFIG_RT_USING_USERSPACE_32BIT_LIMIT is not set
CONFIG_ARCH_USING_NEW_CTX_SWITCH=y
CONFIG___STACKSIZE__=16384
diff --git a/bsp/qemu-virt64-riscv/applications/test/test_mm/SConscript b/bsp/qemu-virt64-riscv/applications/test/test_mm/SConscript
deleted file mode 100644
index 5d2dc708a0..0000000000
--- a/bsp/qemu-virt64-riscv/applications/test/test_mm/SConscript
+++ /dev/null
@@ -1,9 +0,0 @@
-from building import *
-
-cwd = GetCurrentDir()
-src = Glob('*.c') + Glob('*.cpp')
-CPPPATH = [cwd]
-
-group = DefineGroup('Mmu', src, depend = [''], CPPPATH = CPPPATH)
-
-Return('group')
diff --git a/bsp/qemu-virt64-riscv/applications/test/test_mm/test_mm.c b/bsp/qemu-virt64-riscv/applications/test/test_mm/test_mm.c
deleted file mode 100644
index 22b32812f9..0000000000
--- a/bsp/qemu-virt64-riscv/applications/test/test_mm/test_mm.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2006-2022, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- */
-#include <rtthread.h>
-#include <rthw.h>
-
-#if defined(RT_USING_UTEST) && defined(RT_USING_SMART)
-
-#include "riscv_mmu.h"
-#include "mmu.h"
-#include "utest.h"
-
-#define MAPPED 0
-#define UNMAPPED 1
-
-/**
- * @brief Meta data to test V2P API, its structure:
- *
- * {va_start, va_end(included), pa_start, [mapped/unmapped]}
- */
-struct mem_desc test_mem_desc[] = {
- // mapped region
- {0x80000000, 0x80000000 + 0x10000000 - 1, 0x80000000, MAPPED}, // kernel ram region
- {0x0, 0x80000000 - 1, 0x0, MAPPED}, // MMIO region 1
-
- // unmapped region
- {0x100000000, 0x110000000 - 1, 0x100000000, UNMAPPED}, // region for IOREMAP
-};
-
-#define NUM_MEM_DESC (sizeof(test_mem_desc) / sizeof(test_mem_desc[0]))
-
-extern rt_mmu_info mmu_info;
-
-#define TEST_GRANULE_POWER 20
-#define TEST_GRANULE_SIZE (1 << TEST_GRANULE_POWER)
-
-// test board mem region
-static void test_v2p(void)
-{
- struct mem_desc *desc = test_mem_desc;
-
- // test on mapped region
- for (size_t i = 0; i < NUM_MEM_DESC; i++, desc += 1)
- {
- size_t count = (desc->vaddr_end - desc->vaddr_start + 1) >> TEST_GRANULE_POWER;
- void *vstart = (void *)desc->vaddr_start;
- void *pstart = (void *)desc->paddr_start;
- LOG_I("v2p test on VA region [%016lx-%016lx]", vstart, desc->vaddr_end + 1);
-
- int err_flag = 0;
- for (size_t j = 0; j < count; j++, vstart += TEST_GRANULE_SIZE, pstart += TEST_GRANULE_SIZE)
- {
- void *pa = rt_hw_mmu_v2p(&mmu_info, vstart);
- if ((desc->attr == MAPPED && pa != pstart) ||
- (desc->attr == UNMAPPED && pa != 0))
- err_flag = 1;
- }
- uassert_true(err_flag == 0);
- }
-}
-
-// TODO use arrary for test region
-#define MAP_PA ((void *)0xe0001000)
-
-// test va recollection after unmap
-static void test_find_vaddr_recol(void)
-{
- void *map;
- map = rt_hw_mmu_map(&mmu_info, RT_NULL, MAP_PA, 4096, MMU_MAP_K_RWCB);
- rt_hw_mmu_unmap(&mmu_info, map, 4096);
- void *remap;
- remap = rt_hw_mmu_map(&mmu_info, RT_NULL, MAP_PA, 4096, MMU_MAP_K_RWCB);
- rt_hw_mmu_unmap(&mmu_info, map, 4096);
-
- uassert_true(map == remap);
-}
-
-// find vaddr should return a valid VA for rt_hw_mmu_map
-static void test_find_vaddr_valid(void)
-{
- size_t map;
- map = (size_t)rt_hw_mmu_map(&mmu_info, RT_NULL, MAP_PA, 4096, MMU_MAP_K_RWCB);
- rt_hw_mmu_unmap(&mmu_info, (void*)map, 4096);
- LOG_I("Mapped pa %p to %p, %p", MAP_PA, map, mmu_info.vend);
- uassert_true((map >= (mmu_info.vstart << 30)) && (map <= (((mmu_info.vend - mmu_info.vstart) ? mmu_info.vend : mmu_info.vend + 1) << 30)));
-}
-
-// ioremap functionality
-static void test_ioremap(void)
-{
-
-}
-
-static rt_err_t utest_tc_init(void)
-{
- return RT_EOK;
-}
-
-static rt_err_t utest_tc_cleanup(void)
-{
- return RT_EOK;
-}
-
-static void testcase(void)
-{
- UTEST_UNIT_RUN(test_v2p);
- UTEST_UNIT_RUN(test_find_vaddr_recol);
- UTEST_UNIT_RUN(test_find_vaddr_valid);
- UTEST_UNIT_RUN(test_ioremap);
-}
-
-UTEST_TC_EXPORT(testcase, "testcases.libcpu.mmu", utest_tc_init, utest_tc_cleanup, 10);
-#endif /* RT_USING_UTEST */
diff --git a/bsp/qemu-virt64-riscv/driver/board.c b/bsp/qemu-virt64-riscv/driver/board.c
index 6efbd1c128..e1aa2ab977 100644
--- a/bsp/qemu-virt64-riscv/driver/board.c
+++ b/bsp/qemu-virt64-riscv/driver/board.c
@@ -13,6 +13,7 @@
#include <rtdevice.h>
#include "board.h"
+#include "mm_aspace.h"
#include "tick.h"
#include "drv_uart.h"
@@ -31,8 +32,6 @@
rt_region_t init_page_region = {(rt_size_t)RT_HW_PAGE_START, (rt_size_t)RT_HW_PAGE_END};
-rt_mmu_info mmu_info;
-
extern size_t MMUTable[];
struct mem_desc platform_mem_desc[] = {
@@ -43,24 +42,13 @@ struct mem_desc platform_mem_desc[] = {
#endif
-void init_bss(void)
-{
- unsigned int *dst;
-
- dst = &__bss_start;
- while (dst < &__bss_end)
- {
- *dst++ = 0;
- }
-}
-
void primary_cpu_entry(void)
{
extern void entry(void);
/* disable global interrupt */
- init_bss();
rt_hw_interrupt_disable();
+
entry();
}
@@ -69,14 +57,14 @@ void primary_cpu_entry(void)
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
+ /* init data structure */
+ rt_hw_mmu_map_init(&rt_kernel_space, (void *)(USER_VADDR_START - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t *)MMUTable, 0);
+
+ /* init page allocator */
rt_page_init(init_page_region);
- /* init mmu_info structure */
- rt_hw_mmu_map_init(&mmu_info, (void *)(USER_VADDR_START - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t *)MMUTable, 0);
- // this API is reserved currently since PLIC etc had not been porting completely to MMU version
- rt_hw_mmu_kernel_map_init(&mmu_info, 0x00000000UL, 0x80000000);
- /* setup region, and enable MMU */
- rt_hw_mmu_setup(&mmu_info, platform_mem_desc, NUM_MEM_DESC);
+ /* setup region, and enable MMU */
+ rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, NUM_MEM_DESC);
#endif
#ifdef RT_USING_HEAP
diff --git a/bsp/qemu-virt64-riscv/driver/board.h b/bsp/qemu-virt64-riscv/driver/board.h
index 3193346508..3232e09609 100644
--- a/bsp/qemu-virt64-riscv/driver/board.h
+++ b/bsp/qemu-virt64-riscv/driver/board.h
@@ -16,12 +16,17 @@
extern unsigned int __bss_start;
extern unsigned int __bss_end;
-#define RT_HW_HEAP_BEGIN ((void *)&__bss_end)
-#define RT_HW_HEAP_END ((void *)(((rt_size_t)RT_HW_HEAP_BEGIN) + 100 * 1024 * 1024))
+#ifndef RT_USING_SMART
+#define KERNEL_VADDR_START 0x0
+#endif
+
+#define RT_HW_HEAP_BEGIN ((void *)&__bss_end)
+#define RT_HW_HEAP_END ((void *)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024))
#define RT_HW_PAGE_START RT_HW_HEAP_END
-#define RT_HW_PAGE_END ((void *)(((rt_size_t)RT_HW_PAGE_START) + 100 * 1024 * 1024))
+#define RT_HW_PAGE_END ((void *)(KERNEL_VADDR_START + 256 * 1024 * 1024))
void rt_hw_board_init(void);
-void rt_init_user_mem(struct rt_thread *thread, const char *name, unsigned long *entry);
+void rt_init_user_mem(struct rt_thread *thread, const char *name,
+ unsigned long *entry);
#endif
diff --git a/bsp/qemu-virt64-riscv/driver/virt.h b/bsp/qemu-virt64-riscv/driver/virt.h
index 6527ffd137..f059feb50e 100644
--- a/bsp/qemu-virt64-riscv/driver/virt.h
+++ b/bsp/qemu-virt64-riscv/driver/virt.h
@@ -17,7 +17,6 @@
#include <mmu.h>
#include <ioremap.h>
-extern rt_mmu_info mmu_info;
#endif
/* VirtIO */
diff --git a/bsp/qemu-virt64-riscv/qemu-dbg.sh b/bsp/qemu-virt64-riscv/qemu-dbg.sh
index 082555ff6c..a7958ef8e8 100755
--- a/bsp/qemu-virt64-riscv/qemu-dbg.sh
+++ b/bsp/qemu-virt64-riscv/qemu-dbg.sh
@@ -1,3 +1,4 @@
qemu-system-riscv64 -nographic -machine virt -m 256M -kernel rtthread.bin -s -S \
-drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 \
+-netdev user,id=tap0 -device virtio-net-device,netdev=tap0,bus=virtio-mmio-bus.1 \
-device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0
diff --git a/bsp/qemu-virt64-riscv/qemu-v-dbg.sh b/bsp/qemu-virt64-riscv/qemu-v-dbg.sh
index 125f15dd3e..d22af856cb 100644
--- a/bsp/qemu-virt64-riscv/qemu-v-dbg.sh
+++ b/bsp/qemu-virt64-riscv/qemu-v-dbg.sh
@@ -1,3 +1,4 @@
-qemu-system-riscv64 -nographic -machine virt -cpu rv64,v=true,vlen=128,vext_spec=v1.0 -m 256M -kernel rtthread.bin -s -S \
+qemu-system-riscv64 -nographic -machine virt -cpu rv64,v=true,vlen=128,vext_spec=v1.0 -m 256M -kernel rtthread.bin \
-drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 \
+-netdev user,id=tap0 -device virtio-net-device,netdev=tap0,bus=virtio-mmio-bus.1 -s -S \
-device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0
diff --git a/bsp/qemu-virt64-riscv/rtconfig.h b/bsp/qemu-virt64-riscv/rtconfig.h
index fe16539108..67d8b1ad85 100644
--- a/bsp/qemu-virt64-riscv/rtconfig.h
+++ b/bsp/qemu-virt64-riscv/rtconfig.h
@@ -6,7 +6,7 @@
/* RT-Thread Kernel */
-#define RT_NAME_MAX 20
+#define RT_NAME_MAX 24
#define RT_ALIGN_SIZE 8
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
@@ -39,6 +39,7 @@
/* Memory Management */
+#define RT_PAGE_MAX_ORDER 11
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
@@ -124,6 +125,8 @@
#define RT_USING_VIRTIO10
#define RT_USING_VIRTIO_BLK
#define RT_USING_VIRTIO_NET
+#define RT_USING_VIRTIO_CONSOLE
+#define RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR 4
/* Using USB */
@@ -221,118 +224,12 @@
/* RT-Thread Utestcases */
-/* RT-Thread online packages */
-
-/* IoT - internet of things */
-
-
-/* Wi-Fi */
-
-/* Marvell WiFi */
-
-
-/* Wiced WiFi */
-
-
-/* IoT Cloud */
-
-
-/* security packages */
-
-
-/* language packages */
-
-/* JSON: JavaScript Object Notation, a lightweight data-interchange format */
-
-
-/* XML: Extensible Markup Language */
-
-
-/* multimedia packages */
-
-/* LVGL: powerful and easy-to-use embedded GUI library */
-
-
-/* u8g2: a monochrome graphic library */
-
-
-/* PainterEngine: A cross-platform graphics application framework written in C language */
-
-
-/* tools packages */
-
-
-/* system packages */
-
-/* enhanced kernel services */
-
-
-/* acceleration: Assembly language or algorithmic acceleration packages */
-
-
-/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
-
-
-/* Micrium: Micrium software products porting for RT-Thread */
-
-
-/* peripheral libraries and drivers */
-
-
-/* Kendryte SDK */
-
-
-/* AI packages */
-
-
-/* miscellaneous packages */
-
-/* project laboratory */
-
-/* samples: kernel and components samples */
-
-
-/* entertainment: terminal games and other interesting software packages */
-
-
-/* Arduino libraries */
-
-
-/* Projects */
-
-
-/* Sensors */
-
-
-/* Display */
-
-
-/* Timing */
-
-
-/* Data Processing */
-
-
-/* Data Storage */
-
-/* Communication */
-
-
-/* Device Control */
-
-
-/* Other */
-
-/* Signal IO */
-
-
-/* Uncategorized */
-
/* RISC-V QEMU virt64 configs */
#define RISCV_S_MODE
#define BSP_USING_VIRTIO_BLK
#define BSP_USING_VIRTIO_NET
+#define BSP_USING_VIRTIO_CONSOLE
#define BOARD_QEMU_VIRT_RV64
#define ENABLE_FPU
#define ARCH_USING_NEW_CTX_SWITCH
diff --git a/bsp/raspberry-pi/raspi3-64/.config b/bsp/raspberry-pi/raspi3-64/.config
index c50b549948..c55b7a3061 100644
--- a/bsp/raspberry-pi/raspi3-64/.config
+++ b/bsp/raspberry-pi/raspi3-64/.config
@@ -59,6 +59,7 @@ CONFIG_RT_USING_MESSAGEQUEUE=y
#
# Memory Management
#
+CONFIG_RT_PAGE_MAX_ORDER=11
CONFIG_RT_USING_MEMPOOL=y
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
diff --git a/bsp/raspberry-pi/raspi3-64/driver/board.c b/bsp/raspberry-pi/raspi3-64/driver/board.c
index 0d01bfb7a9..614a349973 100644
--- a/bsp/raspberry-pi/raspi3-64/driver/board.c
+++ b/bsp/raspberry-pi/raspi3-64/driver/board.c
@@ -99,8 +99,9 @@ void idle_wfi(void)
*/
void rt_hw_board_init(void)
{
- rt_hw_init_mmu_table(platform_mem_desc, platform_mem_desc_size);
- rt_hw_mmu_init();
+ extern void *MMUTable;
+ rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x80000000, 0x10000000, MMUTable, 0);
+ rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
/* initialize hardware interrupt */
rt_hw_interrupt_init(); // in libcpu/interrupt.c. Set some data structures, no operation on device
diff --git a/bsp/raspberry-pi/raspi3-64/rtconfig.h b/bsp/raspberry-pi/raspi3-64/rtconfig.h
index 9e4d5def3f..900adcff2e 100644
--- a/bsp/raspberry-pi/raspi3-64/rtconfig.h
+++ b/bsp/raspberry-pi/raspi3-64/rtconfig.h
@@ -37,6 +37,7 @@
/* Memory Management */
+#define RT_PAGE_MAX_ORDER 11
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_MEMHEAP
diff --git a/bsp/raspberry-pi/raspi4-32/.config b/bsp/raspberry-pi/raspi4-32/.config
index 4c3cf98351..895df54fcd 100644
--- a/bsp/raspberry-pi/raspi4-32/.config
+++ b/bsp/raspberry-pi/raspi4-32/.config
@@ -59,6 +59,7 @@ CONFIG_RT_USING_MESSAGEQUEUE=y
#
# Memory Management
#
+CONFIG_RT_PAGE_MAX_ORDER=11
CONFIG_RT_USING_MEMPOOL=y
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
@@ -87,7 +88,9 @@ CONFIG_RT_USING_CACHE=y
# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
# CONFIG_RT_USING_CPU_FFS is not set
+CONFIG_ARCH_MM_MMU=y
CONFIG_ARCH_ARM=y
+CONFIG_ARCH_ARM_MMU=y
CONFIG_RT_USING_GIC_V2=y
CONFIG_ARCH_ARMV8=y
@@ -444,7 +447,6 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_SMALL_MODBUS is not set
# CONFIG_PKG_USING_NET_SERVER is not set
# CONFIG_PKG_USING_ZFTP is not set
-# CONFIG_PKG_USING_WOL is not set
#
# security packages
@@ -535,6 +537,7 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_SEGGER_RTT is not set
# CONFIG_PKG_USING_RDB is not set
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ULOG_FILE is not set
# CONFIG_PKG_USING_LOGMGR is not set
# CONFIG_PKG_USING_ADBD is not set
# CONFIG_PKG_USING_COREMARK is not set
@@ -568,6 +571,7 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_CBOX is not set
# CONFIG_PKG_USING_SNOWFLAKE is not set
# CONFIG_PKG_USING_HASH_MATCH is not set
+# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
# CONFIG_PKG_USING_VOFA_PLUS is not set
@@ -644,83 +648,11 @@ CONFIG_RT_LWIP_USING_PING=y
#
# peripheral libraries and drivers
#
-
-#
-# sensors drivers
-#
-# CONFIG_PKG_USING_FINGERPRINT is not set
-# CONFIG_PKG_USING_LSM6DSM is not set
-# CONFIG_PKG_USING_LSM6DSL is not set
-# CONFIG_PKG_USING_LPS22HB is not set
-# CONFIG_PKG_USING_HTS221 is not set
-# CONFIG_PKG_USING_LSM303AGR is not set
-# CONFIG_PKG_USING_BME280 is not set
-# CONFIG_PKG_USING_BME680 is not set
-# CONFIG_PKG_USING_BMA400 is not set
-# CONFIG_PKG_USING_BMI160_BMX160 is not set
-# CONFIG_PKG_USING_SPL0601 is not set
-# CONFIG_PKG_USING_MS5805 is not set
-# CONFIG_PKG_USING_DA270 is not set
-# CONFIG_PKG_USING_DF220 is not set
-# CONFIG_PKG_USING_HSHCAL001 is not set
-# CONFIG_PKG_USING_BH1750 is not set
-# CONFIG_PKG_USING_MPU6XXX is not set
-# CONFIG_PKG_USING_AHT10 is not set
-# CONFIG_PKG_USING_AP3216C is not set
-# CONFIG_PKG_USING_TSL4531 is not set
-# CONFIG_PKG_USING_DS18B20 is not set
-# CONFIG_PKG_USING_DHT11 is not set
-# CONFIG_PKG_USING_DHTXX is not set
-# CONFIG_PKG_USING_GY271 is not set
-# CONFIG_PKG_USING_GP2Y10 is not set
-# CONFIG_PKG_USING_SGP30 is not set
-# CONFIG_PKG_USING_HDC1000 is not set
-# CONFIG_PKG_USING_BMP180 is not set
-# CONFIG_PKG_USING_BMP280 is not set
-# CONFIG_PKG_USING_SHTC1 is not set
-# CONFIG_PKG_USING_BMI088 is not set
-# CONFIG_PKG_USING_HMC5883 is not set
-# CONFIG_PKG_USING_MAX6675 is not set
-# CONFIG_PKG_USING_TMP1075 is not set
-# CONFIG_PKG_USING_SR04 is not set
-# CONFIG_PKG_USING_CCS811 is not set
-# CONFIG_PKG_USING_PMSXX is not set
-# CONFIG_PKG_USING_RT3020 is not set
-# CONFIG_PKG_USING_MLX90632 is not set
-# CONFIG_PKG_USING_MLX90393 is not set
-# CONFIG_PKG_USING_MLX90392 is not set
-# CONFIG_PKG_USING_MLX90397 is not set
-# CONFIG_PKG_USING_MS5611 is not set
-# CONFIG_PKG_USING_MAX31865 is not set
-# CONFIG_PKG_USING_VL53L0X is not set
-# CONFIG_PKG_USING_INA260 is not set
-# CONFIG_PKG_USING_MAX30102 is not set
-# CONFIG_PKG_USING_INA226 is not set
-# CONFIG_PKG_USING_LIS2DH12 is not set
-# CONFIG_PKG_USING_HS300X is not set
-# CONFIG_PKG_USING_ZMOD4410 is not set
-# CONFIG_PKG_USING_ISL29035 is not set
-# CONFIG_PKG_USING_MMC3680KJ is not set
-# CONFIG_PKG_USING_QMP6989 is not set
-# CONFIG_PKG_USING_BALANCE is not set
+# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_SHT2X is not set
# CONFIG_PKG_USING_SHT3X is not set
-# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_ADT74XX is not set
-# CONFIG_PKG_USING_MAX17048 is not set
-
-#
-# touch drivers
-#
-# CONFIG_PKG_USING_GT9147 is not set
-# CONFIG_PKG_USING_GT1151 is not set
-# CONFIG_PKG_USING_GT917S is not set
-# CONFIG_PKG_USING_GT911 is not set
-# CONFIG_PKG_USING_FT6206 is not set
-# CONFIG_PKG_USING_FT5426 is not set
-# CONFIG_PKG_USING_FT6236 is not set
-# CONFIG_PKG_USING_XPT2046_TOUCH is not set
-# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_AS7341 is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ESP_IDF is not set
@@ -747,9 +679,12 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_AGILE_LED is not set
# CONFIG_PKG_USING_AT24CXX is not set
# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
+# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_PCA9685 is not set
# CONFIG_PKG_USING_I2C_TOOLS is not set
# CONFIG_PKG_USING_NRF24L01 is not set
+# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
+# CONFIG_PKG_USING_MAX17048 is not set
# CONFIG_PKG_USING_RPLIDAR is not set
# CONFIG_PKG_USING_AS608 is not set
# CONFIG_PKG_USING_RC522 is not set
@@ -799,7 +734,6 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_RFM300 is not set
# CONFIG_PKG_USING_IO_INPUT_FILTER is not set
# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
-# CONFIG_PKG_USING_LRF_NV7LIDAR is not set
#
# AI packages
@@ -815,12 +749,6 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_NAXOS is not set
#
-# Signal Processing and Control Algorithm Packages
-#
-# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
-# CONFIG_PKG_USING_UKAL is not set
-
-#
# miscellaneous packages
#
@@ -871,6 +799,7 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_VI is not set
# CONFIG_PKG_USING_KI is not set
# CONFIG_PKG_USING_ARMv7M_DWT is not set
+# CONFIG_PKG_USING_UKAL is not set
# CONFIG_PKG_USING_CRCLIB is not set
# CONFIG_PKG_USING_LWGPS is not set
# CONFIG_PKG_USING_STATE_MACHINE is not set
@@ -897,10 +826,12 @@ CONFIG_RT_LWIP_USING_PING=y
#
# Sensors
#
-# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set
-# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
@@ -985,7 +916,6 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
@@ -997,44 +927,11 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set
-# CONFIG_PKG_USING_SEEED_ITG3200 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set
-# CONFIG_PKG_USING_SEEED_MP503 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set
#
# Display
#
# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
-# CONFIG_PKG_USING_SEEED_TM1637 is not set
#
# Timing
@@ -1062,7 +959,6 @@ CONFIG_RT_LWIP_USING_PING=y
#
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
#
# Other
@@ -1083,65 +979,6 @@ CONFIG_RT_LWIP_USING_PING=y
#
# Uncategorized
#
-
-#
-# Privated Packages of RealThread
-#
-# CONFIG_PKG_USING_CODEC is not set
-# CONFIG_PKG_USING_PLAYER is not set
-# CONFIG_PKG_USING_MPLAYER is not set
-# CONFIG_PKG_USING_PERSIMMON_SRC is not set
-# CONFIG_PKG_USING_JS_PERSIMMON is not set
-# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
-
-#
-# Network Utilities
-#
-# CONFIG_PKG_USING_MDNS is not set
-# CONFIG_PKG_USING_UPNP is not set
-# CONFIG_PKG_USING_WICED is not set
-# CONFIG_PKG_USING_CLOUDSDK is not set
-# CONFIG_PKG_USING_POWER_MANAGER is not set
-# CONFIG_PKG_USING_RT_OTA is not set
-# CONFIG_PKG_USING_RTINSIGHT is not set
-# CONFIG_PKG_USING_SMARTCONFIG is not set
-# CONFIG_PKG_USING_RTX is not set
-# CONFIG_RT_USING_TESTCASE is not set
-# CONFIG_PKG_USING_NGHTTP2 is not set
-# CONFIG_PKG_USING_AVS is not set
-# CONFIG_PKG_USING_ALI_LINKKIT is not set
-# CONFIG_PKG_USING_STS is not set
-# CONFIG_PKG_USING_DLMS is not set
-# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
-# CONFIG_PKG_USING_ZBAR is not set
-# CONFIG_PKG_USING_MCF is not set
-# CONFIG_PKG_USING_URPC is not set
-# CONFIG_PKG_USING_DCM is not set
-# CONFIG_PKG_USING_EMQ is not set
-# CONFIG_PKG_USING_CFGM is not set
-# CONFIG_PKG_USING_RT_CMSIS_DAP is not set
-# CONFIG_PKG_USING_SMODULE is not set
-# CONFIG_PKG_USING_SNFD is not set
-# CONFIG_PKG_USING_UDBD is not set
-# CONFIG_PKG_USING_BENCHMARK is not set
-# CONFIG_PKG_USING_UBJSON is not set
-# CONFIG_PKG_USING_DATATYPE is not set
-# CONFIG_PKG_USING_FASTFS is not set
-# CONFIG_PKG_USING_RIL is not set
-# CONFIG_PKG_USING_WATCH_DCM_SVC is not set
-# CONFIG_PKG_USING_WATCH_APP_FWK is not set
-# CONFIG_PKG_USING_GUI_TEST is not set
-# CONFIG_PKG_USING_PMEM is not set
-# CONFIG_PKG_USING_LWRDP is not set
-# CONFIG_PKG_USING_MASAN is not set
-# CONFIG_PKG_USING_BSDIFF_LIB is not set
-# CONFIG_PKG_USING_PRC_DIFF is not set
-
-#
-# RT-Thread Smart
-#
-# CONFIG_PKG_USING_UKERNEL is not set
-# CONFIG_PKG_USING_TRACE_AGENT is not set
CONFIG_BCM2711_SOC=y
# CONFIG_BSP_SUPPORT_FPU is not set
diff --git a/bsp/raspberry-pi/raspi4-32/rtconfig.h b/bsp/raspberry-pi/raspi4-32/rtconfig.h
index 593686676a..33ae1bfb48 100644
--- a/bsp/raspberry-pi/raspi4-32/rtconfig.h
+++ b/bsp/raspberry-pi/raspi4-32/rtconfig.h
@@ -35,6 +35,7 @@
/* Memory Management */
+#define RT_PAGE_MAX_ORDER 11
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
@@ -48,7 +49,9 @@
#define RT_CONSOLE_DEVICE_NAME "uart1"
#define RT_VER_NUM 0x50000
#define RT_USING_CACHE
+#define ARCH_MM_MMU
#define ARCH_ARM
+#define ARCH_ARM_MMU
#define RT_USING_GIC_V2
#define ARCH_ARMV8
@@ -260,11 +263,6 @@
/* peripheral libraries and drivers */
-/* sensors drivers */
-
-
-/* touch drivers */
-
/* Kendryte SDK */
@@ -272,9 +270,6 @@
/* AI packages */
-/* Signal Processing and Control Algorithm Packages */
-
-
/* miscellaneous packages */
/* project laboratory */
@@ -318,14 +313,6 @@
/* Uncategorized */
-/* Privated Packages of RealThread */
-
-
-/* Network Utilities */
-
-
-/* RT-Thread Smart */
-
#define BCM2711_SOC
/* Hardware Drivers Config */
diff --git a/bsp/raspberry-pi/raspi4-64/.config b/bsp/raspberry-pi/raspi4-64/.config
index 64084da049..98d9262646 100644
--- a/bsp/raspberry-pi/raspi4-64/.config
+++ b/bsp/raspberry-pi/raspi4-64/.config
@@ -59,6 +59,7 @@ CONFIG_RT_USING_MESSAGEQUEUE=y
#
# Memory Management
#
+CONFIG_RT_PAGE_MAX_ORDER=11
CONFIG_RT_USING_MEMPOOL=y
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
@@ -88,7 +89,9 @@ CONFIG_RT_USING_CACHE=y
# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
# CONFIG_RT_USING_CPU_FFS is not set
+CONFIG_ARCH_MM_MMU=y
CONFIG_ARCH_ARM=y
+CONFIG_ARCH_ARM_MMU=y
CONFIG_ARCH_ARMV8=y
#
@@ -430,7 +433,6 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
# CONFIG_PKG_USING_SMALL_MODBUS is not set
# CONFIG_PKG_USING_NET_SERVER is not set
# CONFIG_PKG_USING_ZFTP is not set
-# CONFIG_PKG_USING_WOL is not set
#
# security packages
@@ -521,6 +523,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
# CONFIG_PKG_USING_SEGGER_RTT is not set
# CONFIG_PKG_USING_RDB is not set
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ULOG_FILE is not set
# CONFIG_PKG_USING_LOGMGR is not set
# CONFIG_PKG_USING_ADBD is not set
# CONFIG_PKG_USING_COREMARK is not set
@@ -554,6 +557,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
# CONFIG_PKG_USING_CBOX is not set
# CONFIG_PKG_USING_SNOWFLAKE is not set
# CONFIG_PKG_USING_HASH_MATCH is not set
+# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
# CONFIG_PKG_USING_VOFA_PLUS is not set
@@ -630,83 +634,11 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
#
# peripheral libraries and drivers
#
-
-#
-# sensors drivers
-#
-# CONFIG_PKG_USING_FINGERPRINT is not set
-# CONFIG_PKG_USING_LSM6DSM is not set
-# CONFIG_PKG_USING_LSM6DSL is not set
-# CONFIG_PKG_USING_LPS22HB is not set
-# CONFIG_PKG_USING_HTS221 is not set
-# CONFIG_PKG_USING_LSM303AGR is not set
-# CONFIG_PKG_USING_BME280 is not set
-# CONFIG_PKG_USING_BME680 is not set
-# CONFIG_PKG_USING_BMA400 is not set
-# CONFIG_PKG_USING_BMI160_BMX160 is not set
-# CONFIG_PKG_USING_SPL0601 is not set
-# CONFIG_PKG_USING_MS5805 is not set
-# CONFIG_PKG_USING_DA270 is not set
-# CONFIG_PKG_USING_DF220 is not set
-# CONFIG_PKG_USING_HSHCAL001 is not set
-# CONFIG_PKG_USING_BH1750 is not set
-# CONFIG_PKG_USING_MPU6XXX is not set
-# CONFIG_PKG_USING_AHT10 is not set
-# CONFIG_PKG_USING_AP3216C is not set
-# CONFIG_PKG_USING_TSL4531 is not set
-# CONFIG_PKG_USING_DS18B20 is not set
-# CONFIG_PKG_USING_DHT11 is not set
-# CONFIG_PKG_USING_DHTXX is not set
-# CONFIG_PKG_USING_GY271 is not set
-# CONFIG_PKG_USING_GP2Y10 is not set
-# CONFIG_PKG_USING_SGP30 is not set
-# CONFIG_PKG_USING_HDC1000 is not set
-# CONFIG_PKG_USING_BMP180 is not set
-# CONFIG_PKG_USING_BMP280 is not set
-# CONFIG_PKG_USING_SHTC1 is not set
-# CONFIG_PKG_USING_BMI088 is not set
-# CONFIG_PKG_USING_HMC5883 is not set
-# CONFIG_PKG_USING_MAX6675 is not set
-# CONFIG_PKG_USING_TMP1075 is not set
-# CONFIG_PKG_USING_SR04 is not set
-# CONFIG_PKG_USING_CCS811 is not set
-# CONFIG_PKG_USING_PMSXX is not set
-# CONFIG_PKG_USING_RT3020 is not set
-# CONFIG_PKG_USING_MLX90632 is not set
-# CONFIG_PKG_USING_MLX90393 is not set
-# CONFIG_PKG_USING_MLX90392 is not set
-# CONFIG_PKG_USING_MLX90397 is not set
-# CONFIG_PKG_USING_MS5611 is not set
-# CONFIG_PKG_USING_MAX31865 is not set
-# CONFIG_PKG_USING_VL53L0X is not set
-# CONFIG_PKG_USING_INA260 is not set
-# CONFIG_PKG_USING_MAX30102 is not set
-# CONFIG_PKG_USING_INA226 is not set
-# CONFIG_PKG_USING_LIS2DH12 is not set
-# CONFIG_PKG_USING_HS300X is not set
-# CONFIG_PKG_USING_ZMOD4410 is not set
-# CONFIG_PKG_USING_ISL29035 is not set
-# CONFIG_PKG_USING_MMC3680KJ is not set
-# CONFIG_PKG_USING_QMP6989 is not set
-# CONFIG_PKG_USING_BALANCE is not set
+# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_SHT2X is not set
# CONFIG_PKG_USING_SHT3X is not set
-# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_ADT74XX is not set
-# CONFIG_PKG_USING_MAX17048 is not set
-
-#
-# touch drivers
-#
-# CONFIG_PKG_USING_GT9147 is not set
-# CONFIG_PKG_USING_GT1151 is not set
-# CONFIG_PKG_USING_GT917S is not set
-# CONFIG_PKG_USING_GT911 is not set
-# CONFIG_PKG_USING_FT6206 is not set
-# CONFIG_PKG_USING_FT5426 is not set
-# CONFIG_PKG_USING_FT6236 is not set
-# CONFIG_PKG_USING_XPT2046_TOUCH is not set
-# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_AS7341 is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ESP_IDF is not set
@@ -733,9 +665,12 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
# CONFIG_PKG_USING_AGILE_LED is not set
# CONFIG_PKG_USING_AT24CXX is not set
# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
+# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_PCA9685 is not set
# CONFIG_PKG_USING_I2C_TOOLS is not set
# CONFIG_PKG_USING_NRF24L01 is not set
+# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
+# CONFIG_PKG_USING_MAX17048 is not set
# CONFIG_PKG_USING_RPLIDAR is not set
# CONFIG_PKG_USING_AS608 is not set
# CONFIG_PKG_USING_RC522 is not set
@@ -785,7 +720,6 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
# CONFIG_PKG_USING_RFM300 is not set
# CONFIG_PKG_USING_IO_INPUT_FILTER is not set
# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
-# CONFIG_PKG_USING_LRF_NV7LIDAR is not set
#
# AI packages
@@ -801,12 +735,6 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
# CONFIG_PKG_USING_NAXOS is not set
#
-# Signal Processing and Control Algorithm Packages
-#
-# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
-# CONFIG_PKG_USING_UKAL is not set
-
-#
# miscellaneous packages
#
@@ -857,6 +785,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
# CONFIG_PKG_USING_VI is not set
# CONFIG_PKG_USING_KI is not set
# CONFIG_PKG_USING_ARMv7M_DWT is not set
+# CONFIG_PKG_USING_UKAL is not set
# CONFIG_PKG_USING_CRCLIB is not set
# CONFIG_PKG_USING_LWGPS is not set
# CONFIG_PKG_USING_STATE_MACHINE is not set
@@ -883,10 +812,12 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
#
# Sensors
#
-# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set
-# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
@@ -971,7 +902,6 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
@@ -983,44 +913,11 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set
-# CONFIG_PKG_USING_SEEED_ITG3200 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set
-# CONFIG_PKG_USING_SEEED_MP503 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set
#
# Display
#
# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
-# CONFIG_PKG_USING_SEEED_TM1637 is not set
#
# Timing
@@ -1048,7 +945,6 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
#
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
#
# Other
@@ -1069,65 +965,6 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
#
# Uncategorized
#
-
-#
-# Privated Packages of RealThread
-#
-# CONFIG_PKG_USING_CODEC is not set
-# CONFIG_PKG_USING_PLAYER is not set
-# CONFIG_PKG_USING_MPLAYER is not set
-# CONFIG_PKG_USING_PERSIMMON_SRC is not set
-# CONFIG_PKG_USING_JS_PERSIMMON is not set
-# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
-
-#
-# Network Utilities
-#
-# CONFIG_PKG_USING_MDNS is not set
-# CONFIG_PKG_USING_UPNP is not set
-# CONFIG_PKG_USING_WICED is not set
-# CONFIG_PKG_USING_CLOUDSDK is not set
-# CONFIG_PKG_USING_POWER_MANAGER is not set
-# CONFIG_PKG_USING_RT_OTA is not set
-# CONFIG_PKG_USING_RTINSIGHT is not set
-# CONFIG_PKG_USING_SMARTCONFIG is not set
-# CONFIG_PKG_USING_RTX is not set
-# CONFIG_RT_USING_TESTCASE is not set
-# CONFIG_PKG_USING_NGHTTP2 is not set
-# CONFIG_PKG_USING_AVS is not set
-# CONFIG_PKG_USING_ALI_LINKKIT is not set
-# CONFIG_PKG_USING_STS is not set
-# CONFIG_PKG_USING_DLMS is not set
-# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
-# CONFIG_PKG_USING_ZBAR is not set
-# CONFIG_PKG_USING_MCF is not set
-# CONFIG_PKG_USING_URPC is not set
-# CONFIG_PKG_USING_DCM is not set
-# CONFIG_PKG_USING_EMQ is not set
-# CONFIG_PKG_USING_CFGM is not set
-# CONFIG_PKG_USING_RT_CMSIS_DAP is not set
-# CONFIG_PKG_USING_SMODULE is not set
-# CONFIG_PKG_USING_SNFD is not set
-# CONFIG_PKG_USING_UDBD is not set
-# CONFIG_PKG_USING_BENCHMARK is not set
-# CONFIG_PKG_USING_UBJSON is not set
-# CONFIG_PKG_USING_DATATYPE is not set
-# CONFIG_PKG_USING_FASTFS is not set
-# CONFIG_PKG_USING_RIL is not set
-# CONFIG_PKG_USING_WATCH_DCM_SVC is not set
-# CONFIG_PKG_USING_WATCH_APP_FWK is not set
-# CONFIG_PKG_USING_GUI_TEST is not set
-# CONFIG_PKG_USING_PMEM is not set
-# CONFIG_PKG_USING_LWRDP is not set
-# CONFIG_PKG_USING_MASAN is not set
-# CONFIG_PKG_USING_BSDIFF_LIB is not set
-# CONFIG_PKG_USING_PRC_DIFF is not set
-
-#
-# RT-Thread Smart
-#
-# CONFIG_PKG_USING_UKERNEL is not set
-# CONFIG_PKG_USING_TRACE_AGENT is not set
CONFIG_BCM2711_SOC=y
#
diff --git a/bsp/raspberry-pi/raspi4-64/driver/board.c b/bsp/raspberry-pi/raspi4-64/driver/board.c
index 22ae252461..c8c4a5617d 100644
--- a/bsp/raspberry-pi/raspi4-64/driver/board.c
+++ b/bsp/raspberry-pi/raspi4-64/driver/board.c
@@ -86,8 +86,9 @@ void idle_wfi(void)
*/
void rt_hw_board_init(void)
{
- rt_hw_init_mmu_table(platform_mem_desc, platform_mem_desc_size);
- rt_hw_mmu_init();
+ extern void *MMUTable;
+ rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x80000000, 0x10000000, MMUTable, 0);
+ rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
/* initialize hardware interrupt */
rt_hw_interrupt_init(); // in libcpu/interrupt.c. Set some data structures, no operation on device
diff --git a/bsp/raspberry-pi/raspi4-64/rtconfig.h b/bsp/raspberry-pi/raspi4-64/rtconfig.h
index 361e1210a0..88503a7ae1 100644
--- a/bsp/raspberry-pi/raspi4-64/rtconfig.h
+++ b/bsp/raspberry-pi/raspi4-64/rtconfig.h
@@ -36,6 +36,7 @@
/* Memory Management */
+#define RT_PAGE_MAX_ORDER 11
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
@@ -50,7 +51,9 @@
#define RT_VER_NUM 0x50000
#define ARCH_CPU_64BIT
#define RT_USING_CACHE
+#define ARCH_MM_MMU
#define ARCH_ARM
+#define ARCH_ARM_MMU
#define ARCH_ARMV8
/* RT-Thread Components */
@@ -257,11 +260,6 @@
/* peripheral libraries and drivers */
-/* sensors drivers */
-
-
-/* touch drivers */
-
/* Kendryte SDK */
@@ -269,9 +267,6 @@
/* AI packages */
-/* Signal Processing and Control Algorithm Packages */
-
-
/* miscellaneous packages */
/* project laboratory */
@@ -315,14 +310,6 @@
/* Uncategorized */
-/* Privated Packages of RealThread */
-
-
-/* Network Utilities */
-
-
-/* RT-Thread Smart */
-
#define BCM2711_SOC
/* Hardware Drivers Config */
diff --git a/bsp/rockchip/rk3568/.config b/bsp/rockchip/rk3568/.config
index a52b4f55bc..837d79ff33 100644
--- a/bsp/rockchip/rk3568/.config
+++ b/bsp/rockchip/rk3568/.config
@@ -59,6 +59,7 @@ CONFIG_RT_USING_MESSAGEQUEUE=y
#
# Memory Management
#
+CONFIG_RT_PAGE_MAX_ORDER=11
CONFIG_RT_USING_MEMPOOL=y
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
@@ -90,7 +91,9 @@ CONFIG_RT_USING_CACHE=y
# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
# CONFIG_RT_USING_CPU_FFS is not set
+CONFIG_ARCH_MM_MMU=y
CONFIG_ARCH_ARM=y
+CONFIG_ARCH_ARM_MMU=y
CONFIG_ARCH_ARMV8=y
#
@@ -311,7 +314,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_SMALL_MODBUS is not set
# CONFIG_PKG_USING_NET_SERVER is not set
# CONFIG_PKG_USING_ZFTP is not set
-# CONFIG_PKG_USING_WOL is not set
#
# security packages
@@ -402,6 +404,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_SEGGER_RTT is not set
# CONFIG_PKG_USING_RDB is not set
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ULOG_FILE is not set
# CONFIG_PKG_USING_LOGMGR is not set
# CONFIG_PKG_USING_ADBD is not set
# CONFIG_PKG_USING_COREMARK is not set
@@ -435,6 +438,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_CBOX is not set
# CONFIG_PKG_USING_SNOWFLAKE is not set
# CONFIG_PKG_USING_HASH_MATCH is not set
+# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
# CONFIG_PKG_USING_VOFA_PLUS is not set
@@ -511,83 +515,11 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
#
# peripheral libraries and drivers
#
-
-#
-# sensors drivers
-#
-# CONFIG_PKG_USING_FINGERPRINT is not set
-# CONFIG_PKG_USING_LSM6DSM is not set
-# CONFIG_PKG_USING_LSM6DSL is not set
-# CONFIG_PKG_USING_LPS22HB is not set
-# CONFIG_PKG_USING_HTS221 is not set
-# CONFIG_PKG_USING_LSM303AGR is not set
-# CONFIG_PKG_USING_BME280 is not set
-# CONFIG_PKG_USING_BME680 is not set
-# CONFIG_PKG_USING_BMA400 is not set
-# CONFIG_PKG_USING_BMI160_BMX160 is not set
-# CONFIG_PKG_USING_SPL0601 is not set
-# CONFIG_PKG_USING_MS5805 is not set
-# CONFIG_PKG_USING_DA270 is not set
-# CONFIG_PKG_USING_DF220 is not set
-# CONFIG_PKG_USING_HSHCAL001 is not set
-# CONFIG_PKG_USING_BH1750 is not set
-# CONFIG_PKG_USING_MPU6XXX is not set
-# CONFIG_PKG_USING_AHT10 is not set
-# CONFIG_PKG_USING_AP3216C is not set
-# CONFIG_PKG_USING_TSL4531 is not set
-# CONFIG_PKG_USING_DS18B20 is not set
-# CONFIG_PKG_USING_DHT11 is not set
-# CONFIG_PKG_USING_DHTXX is not set
-# CONFIG_PKG_USING_GY271 is not set
-# CONFIG_PKG_USING_GP2Y10 is not set
-# CONFIG_PKG_USING_SGP30 is not set
-# CONFIG_PKG_USING_HDC1000 is not set
-# CONFIG_PKG_USING_BMP180 is not set
-# CONFIG_PKG_USING_BMP280 is not set
-# CONFIG_PKG_USING_SHTC1 is not set
-# CONFIG_PKG_USING_BMI088 is not set
-# CONFIG_PKG_USING_HMC5883 is not set
-# CONFIG_PKG_USING_MAX6675 is not set
-# CONFIG_PKG_USING_TMP1075 is not set
-# CONFIG_PKG_USING_SR04 is not set
-# CONFIG_PKG_USING_CCS811 is not set
-# CONFIG_PKG_USING_PMSXX is not set
-# CONFIG_PKG_USING_RT3020 is not set
-# CONFIG_PKG_USING_MLX90632 is not set
-# CONFIG_PKG_USING_MLX90393 is not set
-# CONFIG_PKG_USING_MLX90392 is not set
-# CONFIG_PKG_USING_MLX90397 is not set
-# CONFIG_PKG_USING_MS5611 is not set
-# CONFIG_PKG_USING_MAX31865 is not set
-# CONFIG_PKG_USING_VL53L0X is not set
-# CONFIG_PKG_USING_INA260 is not set
-# CONFIG_PKG_USING_MAX30102 is not set
-# CONFIG_PKG_USING_INA226 is not set
-# CONFIG_PKG_USING_LIS2DH12 is not set
-# CONFIG_PKG_USING_HS300X is not set
-# CONFIG_PKG_USING_ZMOD4410 is not set
-# CONFIG_PKG_USING_ISL29035 is not set
-# CONFIG_PKG_USING_MMC3680KJ is not set
-# CONFIG_PKG_USING_QMP6989 is not set
-# CONFIG_PKG_USING_BALANCE is not set
+# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_SHT2X is not set
# CONFIG_PKG_USING_SHT3X is not set
-# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_ADT74XX is not set
-# CONFIG_PKG_USING_MAX17048 is not set
-
-#
-# touch drivers
-#
-# CONFIG_PKG_USING_GT9147 is not set
-# CONFIG_PKG_USING_GT1151 is not set
-# CONFIG_PKG_USING_GT917S is not set
-# CONFIG_PKG_USING_GT911 is not set
-# CONFIG_PKG_USING_FT6206 is not set
-# CONFIG_PKG_USING_FT5426 is not set
-# CONFIG_PKG_USING_FT6236 is not set
-# CONFIG_PKG_USING_XPT2046_TOUCH is not set
-# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_AS7341 is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ESP_IDF is not set
@@ -614,9 +546,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_AGILE_LED is not set
# CONFIG_PKG_USING_AT24CXX is not set
# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
+# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_PCA9685 is not set
# CONFIG_PKG_USING_I2C_TOOLS is not set
# CONFIG_PKG_USING_NRF24L01 is not set
+# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
+# CONFIG_PKG_USING_MAX17048 is not set
# CONFIG_PKG_USING_RPLIDAR is not set
# CONFIG_PKG_USING_AS608 is not set
# CONFIG_PKG_USING_RC522 is not set
@@ -666,7 +601,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_RFM300 is not set
# CONFIG_PKG_USING_IO_INPUT_FILTER is not set
# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
-# CONFIG_PKG_USING_LRF_NV7LIDAR is not set
#
# AI packages
@@ -682,12 +616,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_NAXOS is not set
#
-# Signal Processing and Control Algorithm Packages
-#
-# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
-# CONFIG_PKG_USING_UKAL is not set
-
-#
# miscellaneous packages
#
@@ -738,6 +666,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_VI is not set
# CONFIG_PKG_USING_KI is not set
# CONFIG_PKG_USING_ARMv7M_DWT is not set
+# CONFIG_PKG_USING_UKAL is not set
# CONFIG_PKG_USING_CRCLIB is not set
# CONFIG_PKG_USING_LWGPS is not set
# CONFIG_PKG_USING_STATE_MACHINE is not set
@@ -764,10 +693,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
#
# Sensors
#
-# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set
-# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
@@ -852,7 +783,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
@@ -864,44 +794,11 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set
-# CONFIG_PKG_USING_SEEED_ITG3200 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set
-# CONFIG_PKG_USING_SEEED_MP503 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set
#
# Display
#
# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
-# CONFIG_PKG_USING_SEEED_TM1637 is not set
#
# Timing
@@ -929,7 +826,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
#
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
#
# Other
@@ -950,63 +846,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
#
# Uncategorized
#
-
-#
-# Privated Packages of RealThread
-#
-# CONFIG_PKG_USING_CODEC is not set
-# CONFIG_PKG_USING_PLAYER is not set
-# CONFIG_PKG_USING_MPLAYER is not set
-# CONFIG_PKG_USING_PERSIMMON_SRC is not set
-# CONFIG_PKG_USING_JS_PERSIMMON is not set
-# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
-
-#
-# Network Utilities
-#
-# CONFIG_PKG_USING_WICED is not set
-# CONFIG_PKG_USING_CLOUDSDK is not set
-# CONFIG_PKG_USING_POWER_MANAGER is not set
-# CONFIG_PKG_USING_RT_OTA is not set
-# CONFIG_PKG_USING_RTINSIGHT is not set
-# CONFIG_PKG_USING_SMARTCONFIG is not set
-# CONFIG_PKG_USING_RTX is not set
-# CONFIG_RT_USING_TESTCASE is not set
-# CONFIG_PKG_USING_NGHTTP2 is not set
-# CONFIG_PKG_USING_AVS is not set
-# CONFIG_PKG_USING_ALI_LINKKIT is not set
-# CONFIG_PKG_USING_STS is not set
-# CONFIG_PKG_USING_DLMS is not set
-# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
-# CONFIG_PKG_USING_ZBAR is not set
-# CONFIG_PKG_USING_MCF is not set
-# CONFIG_PKG_USING_URPC is not set
-# CONFIG_PKG_USING_DCM is not set
-# CONFIG_PKG_USING_EMQ is not set
-# CONFIG_PKG_USING_CFGM is not set
-# CONFIG_PKG_USING_RT_CMSIS_DAP is not set
-# CONFIG_PKG_USING_SMODULE is not set
-# CONFIG_PKG_USING_SNFD is not set
-# CONFIG_PKG_USING_UDBD is not set
-# CONFIG_PKG_USING_BENCHMARK is not set
-# CONFIG_PKG_USING_UBJSON is not set
-# CONFIG_PKG_USING_DATATYPE is not set
-# CONFIG_PKG_USING_FASTFS is not set
-# CONFIG_PKG_USING_RIL is not set
-# CONFIG_PKG_USING_WATCH_DCM_SVC is not set
-# CONFIG_PKG_USING_WATCH_APP_FWK is not set
-# CONFIG_PKG_USING_GUI_TEST is not set
-# CONFIG_PKG_USING_PMEM is not set
-# CONFIG_PKG_USING_LWRDP is not set
-# CONFIG_PKG_USING_MASAN is not set
-# CONFIG_PKG_USING_BSDIFF_LIB is not set
-# CONFIG_PKG_USING_PRC_DIFF is not set
-
-#
-# RT-Thread Smart
-#
-# CONFIG_PKG_USING_UKERNEL is not set
-# CONFIG_PKG_USING_TRACE_AGENT is not set
CONFIG_SOC_RK3568=y
#
diff --git a/bsp/rockchip/rk3568/driver/board.c b/bsp/rockchip/rk3568/driver/board.c
index 181ca03c3c..592262cb4d 100644
--- a/bsp/rockchip/rk3568/driver/board.c
+++ b/bsp/rockchip/rk3568/driver/board.c
@@ -39,8 +39,9 @@ void idle_wfi(void)
void rt_hw_board_init(void)
{
- rt_hw_init_mmu_table(platform_mem_desc, platform_mem_desc_size);
- rt_hw_mmu_init();
+ extern void *MMUTable;
+ rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x80000000, 0x10000000, MMUTable, 0);
+ rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
/* initialize hardware interrupt */
rt_hw_interrupt_init();
diff --git a/bsp/rockchip/rk3568/rtconfig.h b/bsp/rockchip/rk3568/rtconfig.h
index 3dc4d14e2f..5ac13bcd13 100644
--- a/bsp/rockchip/rk3568/rtconfig.h
+++ b/bsp/rockchip/rk3568/rtconfig.h
@@ -37,6 +37,7 @@
/* Memory Management */
+#define RT_PAGE_MAX_ORDER 11
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_MEMHEAP
@@ -55,7 +56,9 @@
#define RT_VER_NUM 0x50000
#define ARCH_CPU_64BIT
#define RT_USING_CACHE
+#define ARCH_MM_MMU
#define ARCH_ARM
+#define ARCH_ARM_MMU
#define ARCH_ARMV8
/* RT-Thread Components */
@@ -169,11 +172,6 @@
/* peripheral libraries and drivers */
-/* sensors drivers */
-
-
-/* touch drivers */
-
/* Kendryte SDK */
@@ -181,9 +179,6 @@
/* AI packages */
-/* Signal Processing and Control Algorithm Packages */
-
-
/* miscellaneous packages */
/* project laboratory */
@@ -227,14 +222,6 @@
/* Uncategorized */
-/* Privated Packages of RealThread */
-
-
-/* Network Utilities */
-
-
-/* RT-Thread Smart */
-
#define SOC_RK3568
/* Hardware Drivers Config */
diff --git a/components/drivers/virtio/virtio.h b/components/drivers/virtio/virtio.h
index 545c74549d..63e9a73c27 100644
--- a/components/drivers/virtio/virtio.h
+++ b/components/drivers/virtio/virtio.h
@@ -48,8 +48,7 @@
#define VIRTIO_F_RING_PACKED 34
#ifdef RT_USING_SMART
-extern rt_mmu_info mmu_info;
-#define VIRTIO_VA2PA(vaddr) ((rt_ubase_t)rt_hw_mmu_v2p(&mmu_info, vaddr))
+#define VIRTIO_VA2PA(vaddr) ((rt_ubase_t)rt_kmem_v2p(vaddr))
#define VIRTIO_PA2VA(paddr) ((rt_ubase_t)rt_ioremap((void *)paddr, ARCH_PAGE_SIZE))
#else
#define VIRTIO_VA2PA(vaddr) ((rt_ubase_t)vaddr)
diff --git a/components/lwp/arch/aarch64/cortex-a/lwp_arch.c b/components/lwp/arch/aarch64/cortex-a/lwp_arch.c
index 77ed5086a7..50b739b541 100644
--- a/components/lwp/arch/aarch64/cortex-a/lwp_arch.c
+++ b/components/lwp/arch/aarch64/cortex-a/lwp_arch.c
@@ -8,16 +8,13 @@
* 2021-05-18 Jesven first version
*/
-#include <rtthread.h>
#include <rthw.h>
+#include <rtthread.h>
#ifdef ARCH_MM_MMU
-#include <mmu.h>
-#include <page.h>
-#include <lwp_mm_area.h>
-#include <lwp_user_mm.h>
#include <lwp_arch.h>
+#include <lwp_user_mm.h>
extern size_t MMUTable[];
@@ -25,7 +22,7 @@ int arch_user_space_init(struct rt_lwp *lwp)
{
size_t *mmu_table;
- mmu_table = (size_t*)rt_pages_alloc(0);
+ mmu_table = (size_t *)rt_pages_alloc(0);
if (!mmu_table)
{
return -1;
@@ -34,25 +31,28 @@ int arch_user_space_init(struct rt_lwp *lwp)
lwp->end_heap = USER_HEAP_VADDR;
memset(mmu_table, 0, ARCH_PAGE_SIZE);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, ARCH_PAGE_SIZE);
- rt_hw_mmu_map_init(&lwp->mmu_info, (void*)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table, PV_OFFSET);
+
+ lwp->aspace = rt_aspace_create(
+ (void *)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table);
+ if (!lwp->aspace)
+ {
+ return -1;
+ }
return 0;
}
void *arch_kernel_mmu_table_get(void)
{
- return (void*)NULL;
-}
-
-void arch_kuser_init(rt_mmu_info *mmu_info, void *vectors)
-{
+ return (void *)NULL;
}
void arch_user_space_vtable_free(struct rt_lwp *lwp)
{
- if (lwp && lwp->mmu_info.vtable)
+ if (lwp && lwp->aspace->page_table)
{
- rt_pages_free(lwp->mmu_info.vtable, 0);
+ rt_pages_free(lwp->aspace->page_table, 0);
+ lwp->aspace->page_table = NULL;
}
}
@@ -62,9 +62,11 @@ int arch_expand_user_stack(void *addr)
size_t stack_addr = (size_t)addr;
stack_addr &= ~ARCH_PAGE_MASK;
- if ((stack_addr >= (size_t)USER_STACK_VSTART) && (stack_addr < (size_t)USER_STACK_VEND))
+ if ((stack_addr >= (size_t)USER_STACK_VSTART) &&
+ (stack_addr < (size_t)USER_STACK_VEND))
{
- void *map = lwp_map_user(lwp_self(), (void*)stack_addr, ARCH_PAGE_SIZE, 0);
+ void *map =
+ lwp_map_user(lwp_self(), (void *)stack_addr, ARCH_PAGE_SIZE, 0);
if (map || lwp_user_accessable(addr, 1))
{
diff --git a/components/lwp/arch/arm/common/reloc.c b/components/lwp/arch/arm/common/reloc.c
index c54c633aa0..499ba5f589 100644
--- a/components/lwp/arch/arm/common/reloc.c
+++ b/components/lwp/arch/arm/common/reloc.c
@@ -1,3 +1,4 @@
+#include "mm_aspace.h"
#include <rtthread.h>
#include <stdint.h>
#include <string.h>
@@ -18,7 +19,7 @@ typedef struct
} Elf32_sym;
#ifdef ARCH_MM_MMU
-void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf32_sym *dynsym)
+void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf32_sym *dynsym)
{
size_t rel_off;
void* addr;
@@ -36,14 +37,14 @@ void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start,
memcpy(&v2, rel_dyn_start + rel_off + 4, 4);
*/
- addr = rt_hw_mmu_v2p(m_info, (void*)((char*)rel_dyn_start + rel_off));
+ addr = rt_hw_mmu_v2p(aspace, (void*)((char*)rel_dyn_start + rel_off));
addr = (void*)((char*)addr - PV_OFFSET);
memcpy(&v1, addr, 4);
- addr = rt_hw_mmu_v2p(m_info, (void*)((char*)rel_dyn_start + rel_off + 4));
+ addr = rt_hw_mmu_v2p(aspace, (void*)((char*)rel_dyn_start + rel_off + 4));
addr = (void*)((char*)addr - PV_OFFSET);
memcpy(&v2, addr, 4);
- addr = rt_hw_mmu_v2p(m_info, (void*)((char*)text_start + v1));
+ addr = rt_hw_mmu_v2p(aspace, (void*)((char*)text_start + v1));
addr = (void*)((char*)addr - PV_OFFSET);
if ((v2 & 0xff) == R_ARM_RELATIVE)
{
@@ -69,7 +70,7 @@ void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start,
for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
{
//*got_item += (uint32_t)text_start;
- addr = rt_hw_mmu_v2p(m_info, got_item);
+ addr = rt_hw_mmu_v2p(aspace, got_item);
addr = (void*)((char*)addr - PV_OFFSET);
*(uint32_t *)addr += (uint32_t)text_start;
}
diff --git a/components/lwp/arch/arm/cortex-a/lwp_arch.c b/components/lwp/arch/arm/cortex-a/lwp_arch.c
index d2072bb4d1..c7c6d221b3 100644
--- a/components/lwp/arch/arm/cortex-a/lwp_arch.c
+++ b/components/lwp/arch/arm/cortex-a/lwp_arch.c
@@ -8,64 +8,72 @@
* 2019-10-28 Jesven first version
*/
-#include <rtthread.h>
#include <rthw.h>
+#include <rtthread.h>
+#include <stddef.h>
#ifdef ARCH_MM_MMU
-#include <mmu.h>
-#include <page.h>
-#include <lwp_mm_area.h>
-#include <lwp_user_mm.h>
#include <lwp_arch.h>
+#include <lwp_user_mm.h>
-extern size_t MMUTable[];
+#define KPTE_START (KERNEL_VADDR_START >> ARCH_SECTION_SHIFT)
int arch_user_space_init(struct rt_lwp *lwp)
{
size_t *mmu_table;
- mmu_table = (size_t*)rt_pages_alloc(2);
+ mmu_table = (size_t *)rt_pages_alloc(2);
if (!mmu_table)
{
return -1;
}
lwp->end_heap = USER_HEAP_VADDR;
- rt_memcpy(mmu_table + (KERNEL_VADDR_START >> ARCH_SECTION_SHIFT), MMUTable + (KERNEL_VADDR_START >> ARCH_SECTION_SHIFT), ARCH_PAGE_SIZE);
+
+ rt_memcpy(mmu_table + KPTE_START, (size_t *)rt_kernel_space.page_table + KPTE_START, ARCH_PAGE_SIZE);
rt_memset(mmu_table, 0, 3 * ARCH_PAGE_SIZE);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, 4 * ARCH_PAGE_SIZE);
- rt_hw_mmu_map_init(&lwp->mmu_info, (void*)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table, PV_OFFSET);
+ lwp->aspace = rt_aspace_create((void *)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table);
+ if (!lwp->aspace)
+ {
+ return -1;
+ }
return 0;
}
-void *arch_kernel_mmu_table_get(void)
-{
- return (void*)((char*)MMUTable + PV_OFFSET);
-}
+static struct rt_varea kuser_varea;
-void arch_kuser_init(rt_mmu_info *mmu_info, void *vectors)
+void arch_kuser_init(rt_aspace_t aspace, void *vectors)
{
+ const size_t kuser_size = 0x1000;
+ int err;
extern char __kuser_helper_start[], __kuser_helper_end[];
int kuser_sz = __kuser_helper_end - __kuser_helper_start;
- rt_hw_mmu_map_auto(mmu_info, vectors, 0x1000, MMU_MAP_U_RO);
+ err = rt_aspace_map_static(aspace, &kuser_varea, &vectors, kuser_size,
+ MMU_MAP_U_RO, MMF_MAP_FIXED | MMF_PREFETCH,
+ &rt_mm_dummy_mapper, 0);
+ if (err != 0)
+ while (1)
+ ; // early failed
- rt_memcpy((void*)((char*)vectors + 0x1000 - kuser_sz), __kuser_helper_start, kuser_sz);
+ rt_memcpy((void *)((char *)vectors + 0x1000 - kuser_sz), __kuser_helper_start, kuser_sz);
/*
* vectors + 0xfe0 = __kuser_get_tls
* vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8
*/
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void*)((char*)vectors + 0x1000 - kuser_sz), kuser_sz);
- rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, (void*)((char*)vectors + 0x1000 - kuser_sz), kuser_sz);
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)((char *)vectors + 0x1000 - kuser_sz), kuser_sz);
+ rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, (void *)((char *)vectors + 0x1000 - kuser_sz), kuser_sz);
}
void arch_user_space_vtable_free(struct rt_lwp *lwp)
{
- if (lwp && lwp->mmu_info.vtable)
+ if (lwp && lwp->aspace->page_table)
{
- rt_pages_free(lwp->mmu_info.vtable, 2);
+ rt_pages_free(lwp->aspace->page_table, 2);
+ lwp->aspace->page_table = NULL;
}
}
@@ -77,7 +85,7 @@ int arch_expand_user_stack(void *addr)
stack_addr &= ~ARCH_PAGE_MASK;
if ((stack_addr >= (size_t)USER_STACK_VSTART) && (stack_addr < (size_t)USER_STACK_VEND))
{
- void *map = lwp_map_user(lwp_self(), (void*)stack_addr, ARCH_PAGE_SIZE, 0);
+ void *map = lwp_map_user(lwp_self(), (void *)stack_addr, ARCH_PAGE_SIZE, 0);
if (map || lwp_user_accessable(addr, 1))
{
diff --git a/components/lwp/arch/risc-v/rv64/lwp_arch.c b/components/lwp/arch/risc-v/rv64/lwp_arch.c
index 7cc93a4637..fdde5f1370 100644
--- a/components/lwp/arch/risc-v/rv64/lwp_arch.c
+++ b/components/lwp/arch/risc-v/rv64/lwp_arch.c
@@ -15,42 +15,24 @@
* 2021-11-22 JasonHu add lwp_set_thread_context
* 2021-11-30 JasonHu add clone/fork support
*/
-
#include <rthw.h>
+#include <rtthread.h>
+
#include <stddef.h>
#ifdef ARCH_MM_MMU
-#include <mmu.h>
-#include <page.h>
-#include <lwp_mm_area.h>
-#include <lwp_user_mm.h>
+#include <lwp.h>
#include <lwp_arch.h>
+#include <lwp_user_mm.h>
+#include <page.h>
-#include <stack.h>
#include <cpuport.h>
#include <encoding.h>
+#include <stack.h>
extern rt_ubase_t MMUTable[];
-int arch_expand_user_stack(void *addr)
-{
- int ret = 0;
- rt_ubase_t stack_addr = (rt_ubase_t)addr;
-
- stack_addr &= ~PAGE_OFFSET_MASK;
- if ((stack_addr >= (rt_ubase_t)USER_STACK_VSTART) && (stack_addr < (rt_ubase_t)USER_STACK_VEND))
- {
- void *map = lwp_map_user(lwp_self(), (void *)stack_addr, PAGE_SIZE, RT_FALSE);
-
- if (map || lwp_user_accessable(addr, 1))
- {
- ret = 1;
- }
- }
- return ret;
-}
-
void *lwp_copy_return_code_to_user_stack()
{
void lwp_thread_return();
@@ -68,13 +50,6 @@ void *lwp_copy_return_code_to_user_stack()
return RT_NULL;
}
-rt_mmu_info *arch_kernel_get_mmu_info(void)
-{
- extern rt_mmu_info *mmu_info;
-
- return mmu_info;
-}
-
rt_ubase_t lwp_fix_sp(rt_ubase_t cursp)
{
void lwp_thread_return();
@@ -120,9 +95,14 @@ int arch_user_space_init(struct rt_lwp *lwp)
lwp->end_heap = USER_HEAP_VADDR;
- rt_memcpy(mmu_table, MMUTable, PAGE_SIZE);
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, 4 * PAGE_SIZE);
- rt_hw_mmu_map_init(&lwp->mmu_info, (void *)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, (rt_size_t *)mmu_table, 0);
+ rt_memcpy(mmu_table, MMUTable, ARCH_PAGE_SIZE);
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, ARCH_PAGE_SIZE);
+ lwp->aspace = rt_aspace_create(
+ (void *)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table);
+ if (!lwp->aspace)
+ {
+ return -1;
+ }
return 0;
}
@@ -134,9 +114,10 @@ void *arch_kernel_mmu_table_get(void)
void arch_user_space_vtable_free(struct rt_lwp *lwp)
{
- if (lwp && lwp->mmu_info.vtable)
+ if (lwp && lwp->aspace->page_table)
{
- rt_pages_free(lwp->mmu_info.vtable, 0);
+ rt_pages_free(lwp->aspace->page_table, 0);
+ lwp->aspace->page_table = NULL;
}
}
@@ -253,7 +234,7 @@ int arch_set_thread_context(void (*exit)(void), void *new_thread_stack,
*/
void lwp_exec_user(void *args, void *kernel_stack, void *user_entry)
{
- arch_start_umode(args, user_entry, (void*)USER_STACK_VEND, kernel_stack);
+ arch_start_umode(args, user_entry, (void *)USER_STACK_VEND, kernel_stack);
}
void *arch_get_usp_from_uctx(struct rt_user_context *uctx)
diff --git a/components/lwp/arch/risc-v/rv64/lwp_arch.h b/components/lwp/arch/risc-v/rv64/lwp_arch.h
index fa97f58f59..604818ab5c 100644
--- a/components/lwp/arch/risc-v/rv64/lwp_arch.h
+++ b/components/lwp/arch/risc-v/rv64/lwp_arch.h
@@ -10,9 +10,9 @@
#ifndef LWP_ARCH_H__
#define LWP_ARCH_H__
+#include <rthw.h>
#include <lwp.h>
#include <lwp_arch_comm.h>
-#include <riscv_mmu.h>
#ifdef ARCH_MM_MMU
@@ -30,7 +30,7 @@
#define USER_HEAP_VEND 0xffffffffffff0000UL
#define USER_STACK_VSTART 0x270000000UL
#define USER_STACK_VEND USER_HEAP_VADDR
-#define USER_VADDR_START 0x100000000UL
+#define USER_VADDR_START 0x200000000UL
#define USER_VADDR_TOP 0xfffffffffffff000UL
#define USER_LOAD_VADDR 0x200000000
#define LDSO_LOAD_VADDR 0x200000000
@@ -49,9 +49,6 @@
extern "C" {
#endif
-rt_mmu_info* arch_kernel_get_mmu_info(void);
-int arch_expand_user_stack(void *addr);
-
rt_inline unsigned long rt_hw_ffz(unsigned long x)
{
return __builtin_ffsl(~x) - 1;
@@ -59,7 +56,7 @@ rt_inline unsigned long rt_hw_ffz(unsigned long x)
rt_inline void icache_invalid_all(void)
{
- //TODO:
+ rt_hw_cpu_icache_invalidate_all();
}
#ifdef __cplusplus
diff --git a/components/lwp/arch/risc-v/rv64/reloc.c b/components/lwp/arch/risc-v/rv64/reloc.c
index def0f82fc1..bdd8d310aa 100644
--- a/components/lwp/arch/risc-v/rv64/reloc.c
+++ b/components/lwp/arch/risc-v/rv64/reloc.c
@@ -1,3 +1,4 @@
+#include "mm_aspace.h"
#include <rtthread.h>
#include <stdint.h>
#include <string.h>
@@ -18,7 +19,7 @@ typedef struct
} Elf64_sym;
#ifdef ARCH_MM_MMU
-void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf64_sym *dynsym)
+void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf64_sym *dynsym)
{
size_t rel_off;
void* addr;
@@ -31,12 +32,12 @@ void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start,
{
uint32_t v1, v2;
- addr = rt_hw_mmu_v2p(m_info, (void *)(((rt_size_t)rel_dyn_start) + rel_off));
+ addr = rt_hw_mmu_v2p(aspace, (void *)(((rt_size_t)rel_dyn_start) + rel_off));
memcpy(&v1, addr, 4);
- addr = rt_hw_mmu_v2p(m_info, (void *)(((rt_size_t)rel_dyn_start) + rel_off + 4));
+ addr = rt_hw_mmu_v2p(aspace, (void *)(((rt_size_t)rel_dyn_start) + rel_off + 4));
memcpy(&v2, addr, 4);
- addr = rt_hw_mmu_v2p(m_info, (void *)((rt_size_t)text_start + v1));
+ addr = rt_hw_mmu_v2p(aspace, (void *)((rt_size_t)text_start + v1));
if ((v2 & 0xff) == R_ARM_RELATIVE)
{
*(rt_size_t*)addr += (rt_size_t)text_start;
@@ -58,7 +59,7 @@ void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start,
for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
{
- addr = rt_hw_mmu_v2p(m_info, got_item);
+ addr = rt_hw_mmu_v2p(aspace, got_item);
*(rt_size_t *)addr += (rt_size_t)text_start;
}
}
diff --git a/components/lwp/ioremap.c b/components/lwp/ioremap.c
index 525c8306c0..5a82a58c28 100644
--- a/components/lwp/ioremap.c
+++ b/components/lwp/ioremap.c
@@ -12,33 +12,40 @@
#include <ioremap.h>
-#ifdef ARCH_MM_MMU
+#ifdef RT_USING_SMART
#include <mmu.h>
-#include <lwp_mm_area.h>
#include <lwp_mm.h>
+#include <mm_aspace.h>
-static struct lwp_avl_struct *k_map_area;
-extern rt_mmu_info mmu_info;
+#define DBG_TAG "mm.ioremap"
+#define DBG_LVL DBG_LOG
+#include <rtdbg.h>
-static void _iounmap_range(void *addr, size_t size)
+enum ioremap_type
{
- void *va = RT_NULL, *pa = RT_NULL;
- int i = 0;
+ MM_AREA_TYPE_PHY,
+ MM_AREA_TYPE_PHY_CACHED
+};
- for (va = addr, i = 0; i < size; va = (void *)((char *)va + ARCH_PAGE_SIZE), i += ARCH_PAGE_SIZE)
- {
- pa = rt_hw_mmu_v2p(&mmu_info, va);
- if (pa)
- {
- rt_hw_mmu_unmap(&mmu_info, va, ARCH_PAGE_SIZE);
- }
- }
-}
+void *rt_ioremap_start;
+size_t rt_ioremap_size;
-static void *_ioremap_type(void *paddr, size_t size, int type)
+static void *_ioremap_type(void *paddr, size_t size, enum ioremap_type type)
{
void *v_addr = NULL;
size_t attr;
+ size_t lo_off;
+ int err;
+
+ lo_off = (uintptr_t)paddr & ARCH_PAGE_MASK;
+
+ struct rt_mm_va_hint hint = {
+ .prefer = ARCH_MAP_FAILED,
+ .map_size = RT_ALIGN(size + lo_off, ARCH_PAGE_SIZE),
+ .flags = 0,
+ .limit_start = rt_ioremap_start,
+ .limit_range_size = rt_ioremap_size,
+ };
switch (type)
{
@@ -51,19 +58,17 @@ static void *_ioremap_type(void *paddr, size_t size, int type)
default:
return v_addr;
}
+ err = rt_aspace_map_phy(&rt_kernel_space, &hint, attr, MM_PA_TO_OFF(paddr), &v_addr);
- rt_mm_lock();
- v_addr = rt_hw_mmu_map(&mmu_info, 0, paddr, size, attr);
- if (v_addr)
+ if (err)
{
- int ret = lwp_map_area_insert(&k_map_area, (size_t)v_addr, size, type);
- if (ret != 0)
- {
- _iounmap_range(v_addr, size);
- v_addr = NULL;
- }
+ LOG_W("IOREMAP 0x%lx failed", paddr);
+ v_addr = NULL;
+ }
+ else
+ {
+ v_addr = v_addr + lo_off;
}
- rt_mm_unlock();
return v_addr;
}
@@ -84,18 +89,7 @@ void *rt_ioremap_cached(void *paddr, size_t size)
void rt_iounmap(volatile void *vaddr)
{
- struct lwp_avl_struct *ma_avl_node;
-
- rt_mm_lock();
- ma_avl_node = lwp_map_find(k_map_area, (size_t)vaddr);
- if (ma_avl_node)
- {
- struct rt_mm_area_struct *ma = (struct rt_mm_area_struct *)ma_avl_node->data;
-
- _iounmap_range((void *)ma->addr, ma->size);
- lwp_map_area_remove(&k_map_area, (size_t)vaddr);
- }
- rt_mm_unlock();
+ rt_aspace_unmap(&rt_kernel_space, (void *)vaddr, 1);
}
#else
diff --git a/components/lwp/ioremap.h b/components/lwp/ioremap.h
index a2d64523f1..2611b3a520 100644
--- a/components/lwp/ioremap.h
+++ b/components/lwp/ioremap.h
@@ -10,6 +10,8 @@
#ifndef __IOREMAP_H__
#define __IOREMAP_H__
+#include <stddef.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -19,6 +21,9 @@ void *rt_ioremap_nocache(void *paddr, size_t size);
void *rt_ioremap_cached (void *paddr, size_t size);
void rt_iounmap(volatile void *addr);
+extern void *rt_ioremap_start;
+extern size_t rt_ioremap_size;
+
#ifdef __cplusplus
}
#endif
diff --git a/components/lwp/lwp.c b/components/lwp/lwp.c
index 672fb26536..cc4a1f3974 100644
--- a/components/lwp/lwp.c
+++ b/components/lwp/lwp.c
@@ -37,7 +37,6 @@
#include <rtdbg.h>
#ifdef ARCH_MM_MMU
-#include <lwp_mm_area.h>
#include <lwp_user_mm.h>
#endif /* end of ARCH_MM_MMU */
@@ -183,7 +182,7 @@ struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **argv, char
return RT_NULL;
}
- args_k = (size_t *)rt_hw_mmu_v2p(&lwp->mmu_info, args);
+ args_k = (size_t *)lwp_v2p(lwp, args);
args_k = (size_t *)((size_t)args_k - PV_OFFSET);
/* argc, argv[], 0, envp[], 0 , aux[] */
@@ -511,7 +510,6 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
void *pa, *va;
void *va_self;
- rt_mmu_info *m_info = &lwp->mmu_info;
#endif
if (len < sizeof eheader)
@@ -613,7 +611,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
LOG_E("lwp map user failed!");
return -RT_ERROR;
}
- pa = rt_hw_mmu_v2p(m_info, va);
+ pa = lwp_v2p(lwp, va);
process_header = (uint8_t *)pa - PV_OFFSET;
#else
process_header = (uint8_t *)rt_malloc(process_header_size + sizeof(char[16]));
@@ -646,7 +644,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
random = (uint8_t *)(USER_VADDR_TOP - ARCH_PAGE_SIZE - sizeof(char[16]));
- krandom = (uint8_t *)rt_hw_mmu_v2p(m_info, random);
+ krandom = (uint8_t *)lwp_v2p(lwp, random);
krandom = (uint8_t *)krandom - PV_OFFSET;
rt_memcpy(krandom, &random_value, sizeof random_value);
#else
@@ -738,7 +736,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
{
if (user_area[i].size != 0)
{
- va = lwp_map_user(lwp, user_area[i].start, user_area[i].size, (int)(i == 0));
+ va = lwp_map_user(lwp, user_area[i].start, user_area[i].size, (i == 0));
if (!va || (va != user_area[i].start))
{
result = -RT_ERROR;
@@ -836,7 +834,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
read_len = 0;
while (size)
{
- pa = rt_hw_mmu_v2p(m_info, va);
+ pa = lwp_v2p(lwp, va);
va_self = (void *)((char *)pa - PV_OFFSET);
LOG_D("va_self = %p pa = %p", va_self, pa);
tmp_len = (size < ARCH_PAGE_SIZE) ? size : ARCH_PAGE_SIZE;
@@ -864,7 +862,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
while (size)
{
size_s = (size < ARCH_PAGE_SIZE - off) ? size : ARCH_PAGE_SIZE - off;
- pa = rt_hw_mmu_v2p(m_info, va);
+ pa = lwp_v2p(lwp, va);
va_self = (void *)((char *)pa - PV_OFFSET);
memset((void *)((char *)va_self + off), 0, size_s);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)((char *)va_self + off), size_s);
@@ -942,7 +940,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
check_read(read_len, dynsym_size);
}
#ifdef ARCH_MM_MMU
- arch_elf_reloc(m_info, (void *)load_off, rel_dyn_start, rel_dyn_size, got_start, got_size, dynsym);
+ arch_elf_reloc(lwp->aspace, (void *)load_off, rel_dyn_start, rel_dyn_size, got_start, got_size, dynsym);
#else
arch_elf_reloc((void *)load_off, rel_dyn_start, rel_dyn_size, got_start, got_size, dynsym);
@@ -1151,7 +1149,7 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
return -ENOMEM;
}
#ifdef ARCH_MM_MMU
- if (lwp_user_space_init(lwp) != 0)
+ if (lwp_user_space_init(lwp, 0) != 0)
{
lwp_tid_put(tid);
lwp_ref_dec(lwp);
diff --git a/components/lwp/lwp.h b/components/lwp/lwp.h
index 57230c9b70..7fbcb0c666 100644
--- a/components/lwp/lwp.h
+++ b/components/lwp/lwp.h
@@ -28,6 +28,7 @@
#include "lwp_signal.h"
#include "lwp_syscall.h"
#include "lwp_avl.h"
+#include "mm_aspace.h"
#ifdef ARCH_MM_MMU
#include "lwp_shm.h"
@@ -57,12 +58,18 @@ extern "C" {
#define LWP_ARG_MAX 8
+struct rt_lwp_objs
+{
+ rt_aspace_t source;
+ struct rt_mem_obj mem_obj;
+};
+
struct rt_lwp
{
#ifdef ARCH_MM_MMU
- rt_mmu_info mmu_info;
- struct lwp_avl_struct *map_area;
size_t end_heap;
+ rt_aspace_t aspace;
+ struct rt_lwp_objs *lwp_obj;
#else
#ifdef ARCH_MM_MPU
struct rt_mpu_info mpu_info;
@@ -154,7 +161,7 @@ int lwp_execve(char *filename, int debug, int argc, char **argv, char **envp);
/*create by lwp_setsid.c*/
int setsid(void);
#ifdef ARCH_MM_MMU
-void lwp_mmu_switch(struct rt_thread *thread);
+void lwp_aspace_switch(struct rt_thread *thread);
#endif
void lwp_user_setting_save(rt_thread_t thread);
void lwp_user_setting_restore(rt_thread_t thread);
diff --git a/components/lwp/lwp_arch_comm.h b/components/lwp/lwp_arch_comm.h
index 5bc317758c..462c0303f7 100644
--- a/components/lwp/lwp_arch_comm.h
+++ b/components/lwp/lwp_arch_comm.h
@@ -10,7 +10,9 @@
#ifndef __LWP_ARCH_COMM__
#define __LWP_ARCH_COMM__
+#include <mm_aspace.h>
#include <rtthread.h>
+#include <mmu.h>
/**
* APIs that must port to all architectures
@@ -24,7 +26,9 @@ void arch_ret_to_user();
/* ELF relocation */
#ifdef ARCH_MM_MMU
-void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, void *dynsym);
+
+struct rt_lwp;
+void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, void *dynsym);
#else
void arch_elf_reloc(void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, void *dynsym);
#endif
@@ -42,7 +46,7 @@ void *arch_get_user_sp(void);
int arch_user_space_init(struct rt_lwp *lwp);
void arch_user_space_vtable_free(struct rt_lwp *lwp);
void *arch_kernel_mmu_table_get(void);
-void arch_kuser_init(rt_mmu_info *mmu_info, void *vectors);
+void arch_kuser_init(rt_aspace_t aspace, void *vectors);
int arch_expand_user_stack(void *addr);
/* thread id register */
diff --git a/components/lwp/lwp_mm_area.c b/components/lwp/lwp_mm_area.c
deleted file mode 100644
index 93f7c2a43c..0000000000
--- a/components/lwp/lwp_mm_area.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2019-10-28 Jesven first version
- */
-#include <rtthread.h>
-
-#ifdef ARCH_MM_MMU
-#include <lwp_mm_area.h>
-
-int lwp_map_area_insert(struct lwp_avl_struct **avl_tree, size_t addr, size_t size, int ma_type)
-{
- struct lwp_avl_struct *node = RT_NULL;
- struct rt_mm_area_struct *ma = RT_NULL;
-
- if (!size)
- {
- return -1;
- }
- ma = (struct rt_mm_area_struct *)rt_malloc(sizeof(struct rt_mm_area_struct));
- if (!ma)
- {
- return -1;
- }
- ma->addr = addr;
- ma->size = size;
- ma->type = ma_type;
-
- node = (struct lwp_avl_struct *)rt_malloc(sizeof(struct lwp_avl_struct));
- if (!node)
- {
- rt_free(ma);
- return -1;
- }
- memset(node, 0, sizeof(struct lwp_avl_struct));
-
- node->avl_key = ma->addr;
- node->data = (void *)ma;
- lwp_avl_insert(node, avl_tree);
- return 0;
-}
-
-void lwp_map_area_remove(struct lwp_avl_struct **avl_tree, size_t addr)
-{
- struct lwp_avl_struct *node = RT_NULL;
-
- node = lwp_avl_find(addr, *avl_tree);
- if (!node)
- {
- return;
- }
- lwp_avl_remove(node, avl_tree);
- rt_free(node->data);
- rt_free(node);
-}
-
-struct lwp_avl_struct* lwp_map_find(struct lwp_avl_struct* ptree, size_t addr)
-{
- struct lwp_avl_struct *node = ptree;
-
- while (1)
- {
- if (!node)
- {
- return node;
- }
- if ((size_t)node->avl_key <= addr)
- {
- struct rt_mm_area_struct *ma = (struct rt_mm_area_struct *)node->data;
- if ((ma->addr <= addr) && (addr < ma->addr + ma->size))
- {
- /* find area */
- break;
- }
- node = node->avl_right;
- }
- else
- {
- node = node->avl_left;
- }
- }
- return node;
-}
-
-struct lwp_avl_struct* lwp_map_find_first(struct lwp_avl_struct* ptree)
-{
- if (ptree == AVL_EMPTY)
- {
- return (struct lwp_avl_struct *)0;
- }
- while (1)
- {
- if (!ptree->avl_left)
- {
- break;
- }
- ptree = ptree->avl_left;
- }
- return ptree;
-}
-
-int top_mem_fun(struct lwp_avl_struct* ptree, void *arg)
-{
- size_t *vs = (size_t *)arg;
- struct rt_mm_area_struct *ma;
-
- ma = (struct rt_mm_area_struct *)ptree->data;
- *vs += ma->size;
- return 0;
-}
-
-size_t lwp_vmem_count(struct lwp_avl_struct *ptree)
-{
- size_t vsize = 0;
- lwp_avl_traversal(ptree, top_mem_fun, &vsize);
- return vsize;
-}
-#endif
diff --git a/components/lwp/lwp_mm_area.h b/components/lwp/lwp_mm_area.h
deleted file mode 100644
index 9fea5d49cb..0000000000
--- a/components/lwp/lwp_mm_area.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2006-2020, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2019-10-28 Jesven first version
- */
-#ifndef __LWP_MM_AREA_H__
-#define __LWP_MM_AREA_H__
-
-#include <string.h>
-#include <stdint.h>
-
-#include <lwp_avl.h>
-
-#ifdef ARCH_MM_MMU
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum
-{
- MM_AREA_TYPE_PHY = 0, /* mm_area physical address is IO register or reserved memory no cached*/
- MM_AREA_TYPE_PHY_CACHED, /* mm_area physical address is IO register or reserved memory with cached */
- MM_AREA_TYPE_SHM, /* mm_area physical address is shared memory */
- MM_AREA_TYPE_DATA, /* mm_area physical address is alloced from page manager for data */
- MM_AREA_TYPE_TEXT, /* mm_area physical address is alloced from page manager for text */
- MM_AREA_TYPE_UNKNOW,
-};
-
-struct rt_mm_area_struct
-{
- size_t addr;
- size_t size;
- int type;
-};
-
-int lwp_map_area_insert(struct lwp_avl_struct **avl_tree, size_t addr, size_t size, int ma_type);
-void lwp_map_area_remove(struct lwp_avl_struct **avl_tree, size_t addr);
-struct lwp_avl_struct* lwp_map_find(struct lwp_avl_struct* ptree, size_t addr);
-struct lwp_avl_struct* lwp_map_find_first(struct lwp_avl_struct* ptree);
-size_t lwp_vmem_count(struct lwp_avl_struct *ptree);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-#endif /*__LWP_MM_AREA_H__*/
diff --git a/components/lwp/lwp_shm.c b/components/lwp/lwp_shm.c
index 135cff5c9c..3cfdda7404 100644
--- a/components/lwp/lwp_shm.c
+++ b/components/lwp/lwp_shm.c
@@ -15,12 +15,15 @@
#include <lwp_shm.h>
#include <lwp_mm.h>
-#include <lwp_mm_area.h>
#include <lwp_user_mm.h>
+#include <mmu.h>
+#include <mm_aspace.h>
+#include <mm_flag.h>
/* the kernel structure to represent a share-memory */
struct lwp_shm_struct
{
+ struct rt_mem_obj mem_obj;
size_t addr; /* point to the next item in the free list when not used */
size_t size;
int ref;
@@ -34,6 +37,35 @@ static int shm_free_list = -1; /* the single-direct list of freed items */
static int shm_id_used = 0; /* the latest allocated item in the array */
static struct lwp_shm_struct _shm_ary[RT_LWP_SHM_MAX_NR];
+static const char *get_shm_name(rt_varea_t varea)
+{
+ return "user.shm";
+}
+
+static void on_shm_varea_open(struct rt_varea *varea)
+{
+ struct lwp_shm_struct *shm;
+ shm = rt_container_of(varea->mem_obj, struct lwp_shm_struct, mem_obj);
+ shm->ref += 1;
+}
+
+static void on_shm_varea_close(struct rt_varea *varea)
+{
+ struct lwp_shm_struct *shm;
+ shm = rt_container_of(varea->mem_obj, struct lwp_shm_struct, mem_obj);
+ shm->ref -= 1;
+}
+
+static void on_shm_page_fault(struct rt_varea *varea, struct rt_mm_fault_msg *msg)
+{
+ struct lwp_shm_struct *shm;
+ shm = rt_container_of(varea->mem_obj, struct lwp_shm_struct, mem_obj);
+ msg->response.status = MM_FAULT_STATUS_OK;
+ msg->response.vaddr = (void *)shm->addr;
+ msg->response.size = shm->size;
+ return ;
+}
+
/*
* Try to allocate an structure 'lwp_shm_struct' from the freed list or the
* static array.
@@ -110,6 +142,12 @@ static int _lwp_shmget(size_t key, size_t size, int create)
p->size = (1UL << (bit + ARCH_PAGE_SHIFT));
p->ref = 0;
p->key = key;
+ p->mem_obj.get_name = get_shm_name;
+ p->mem_obj.on_page_fault = on_shm_page_fault;
+ p->mem_obj.on_varea_open = on_shm_varea_open;
+ p->mem_obj.on_varea_close = on_shm_varea_close;
+ p->mem_obj.hint_free = NULL;
+ p->mem_obj.on_page_offload = NULL;
/* then insert it into the balancing binary tree */
node_key = (struct lwp_avl_struct *)rt_malloc(sizeof(struct lwp_avl_struct) * 2);
@@ -212,15 +250,15 @@ int lwp_shmrm(int id)
{
int ret = 0;
- rt_mm_lock();
ret = _lwp_shmrm(id);
- rt_mm_unlock();
+
return ret;
}
/* Map the shared memory specified by 'id' to the specified virtual address. */
static void *_lwp_shmat(int id, void *shm_vaddr)
{
+ int err;
struct rt_lwp *lwp = RT_NULL;
struct lwp_avl_struct *node_key = RT_NULL;
struct lwp_shm_struct *p = RT_NULL;
@@ -244,10 +282,16 @@ static void *_lwp_shmat(int id, void *shm_vaddr)
{
return RT_NULL;
}
- va = lwp_map_user_type(lwp, shm_vaddr, (void *)p->addr, p->size, 1, MM_AREA_TYPE_SHM);
- if (va)
+ if (shm_vaddr == 0)
+ va = ARCH_MAP_FAILED;
+ else
+ va = shm_vaddr;
+
+ err = rt_aspace_map(lwp->aspace, &va, p->size, MMU_MAP_U_RWCB, MMF_PREFETCH,
+ &p->mem_obj, 0);
+ if (err != RT_EOK)
{
- p->ref++;
+ va = 0;
}
return va;
}
@@ -261,9 +305,9 @@ void *lwp_shmat(int id, void *shm_vaddr)
{
return RT_NULL;
}
- rt_mm_lock();
+
ret = _lwp_shmat(id, shm_vaddr);
- rt_mm_unlock();
+
return ret;
}
@@ -276,7 +320,7 @@ static struct lwp_shm_struct *_lwp_shm_struct_get(struct rt_lwp *lwp, void *shm_
{
return RT_NULL;
}
- pa = rt_hw_mmu_v2p(&lwp->mmu_info, shm_vaddr); /* physical memory */
+ pa = lwp_v2p(lwp, shm_vaddr); /* physical memory */
node_pa = lwp_avl_find((size_t)pa, shm_tree_pa);
if (!node_pa)
@@ -343,14 +387,15 @@ int _lwp_shmdt(void *shm_vaddr)
{
return -1;
}
- ret = _lwp_shm_ref_dec(lwp, shm_vaddr);
- if (ret >= 0)
+
+ ret = rt_aspace_unmap(lwp->aspace, shm_vaddr, 1);
+ if (ret != RT_EOK)
{
- lwp_unmap_user_phy(lwp, shm_vaddr);
- return 0;
+ ret = -1;
}
- return -1;
+ return ret;
}
+
/* A wrapping function: detach the mapped shared memory. */
int lwp_shmdt(void *shm_vaddr)
{
diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c
index 16ac7e99ee..b0f69fd690 100644
--- a/components/lwp/lwp_syscall.c
+++ b/components/lwp/lwp_syscall.c
@@ -13,8 +13,11 @@
*/
#define _GNU_SOURCE
/* RT-Thread System call */
+#include <rtthread.h>
#include <rthw.h>
#include <board.h>
+#include <mm_aspace.h>
+#include <string.h>
#include <lwp.h>
#ifdef ARCH_MM_MMU
@@ -1282,7 +1285,7 @@ rt_err_t sys_timer_create(clockid_t clockid, struct sigevent *restrict sevp, tim
#ifdef ARCH_MM_MMU
struct sigevent sevp_k;
timer_t timerid_k;
- struct sigevent evp_default;
+
if (sevp == NULL)
{
sevp_k.sigev_notify = SIGEV_SIGNAL;
@@ -1362,7 +1365,7 @@ rt_thread_t sys_thread_create(void *arg[])
lwp = rt_thread_self()->lwp;
lwp_ref_inc(lwp);
#ifdef ARCH_MM_MMU
- user_stack = lwp_map_user(lwp, 0, (size_t)arg[3], 0);
+ user_stack = lwp_map_user(lwp, 0, (size_t)arg[3], 0);
if (!user_stack)
{
goto fail;
@@ -1605,11 +1608,15 @@ rt_weak long sys_clone(void *arg[])
return _sys_clone(arg);
}
-int lwp_dup_user(struct lwp_avl_struct* ptree, void *arg);
+int lwp_dup_user(rt_varea_t varea, void *arg);
static int _copy_process(struct rt_lwp *dest_lwp, struct rt_lwp *src_lwp)
{
- return lwp_avl_traversal(src_lwp->map_area, lwp_dup_user, dest_lwp);
+ int err;
+ dest_lwp->lwp_obj->source = src_lwp->aspace;
+ err = rt_aspace_traversal(src_lwp->aspace, lwp_dup_user, dest_lwp);
+ dest_lwp->lwp_obj->source = NULL;
+ return err;
}
static void lwp_struct_copy(struct rt_lwp *dst, struct rt_lwp *src)
@@ -1694,7 +1701,7 @@ int _sys_fork(void)
}
/* user space init */
- if (lwp_user_space_init(lwp) != 0)
+ if (lwp_user_space_init(lwp, 1) != 0)
{
SET_ERRNO(ENOMEM);
goto fail;
@@ -2302,7 +2309,7 @@ int sys_execve(const char *path, char *const argv[], char *const envp[])
rt_memset(new_lwp, 0, sizeof(struct rt_lwp));
new_lwp->ref = 1;
lwp_user_object_lock_init(new_lwp);
- ret = arch_user_space_init(new_lwp);
+ ret = lwp_user_space_init(new_lwp, 0);
if (ret != 0)
{
SET_ERRNO(ENOMEM);
@@ -2371,8 +2378,9 @@ int sys_execve(const char *path, char *const argv[], char *const envp[])
rt_pages_free(page, 0);
#ifdef ARCH_MM_MMU
- _swap_lwp_data(lwp, new_lwp, rt_mmu_info, mmu_info);
- _swap_lwp_data(lwp, new_lwp, struct lwp_avl_struct *, map_area);
+ _swap_lwp_data(lwp, new_lwp, struct rt_aspace *, aspace);
+ _swap_lwp_data(lwp, new_lwp, struct rt_lwp_objs *, lwp_obj);
+
_swap_lwp_data(lwp, new_lwp, size_t, end_heap);
#endif
_swap_lwp_data(lwp, new_lwp, uint8_t, lwp_type);
@@ -2392,7 +2400,7 @@ int sys_execve(const char *path, char *const argv[], char *const envp[])
/* to do: clsoe files with flag CLOEXEC */
- lwp_mmu_switch(thread);
+ lwp_aspace_switch(thread);
rt_hw_interrupt_enable(level);
@@ -4562,17 +4570,17 @@ const static void* func_table[] =
SYSCALL_USPACE(SYSCALL_SIGN(sys_madvise)),
SYSCALL_SIGN(sys_sched_setparam),
SYSCALL_SIGN(sys_sched_getparam),
- SYSCALL_SIGN(sys_sched_get_priority_max),
+ SYSCALL_SIGN(sys_sched_get_priority_max), /* 150 */
SYSCALL_SIGN(sys_sched_get_priority_min),
SYSCALL_SIGN(sys_sched_setscheduler),
SYSCALL_SIGN(sys_sched_getscheduler),
SYSCALL_SIGN(sys_setaffinity),
- SYSCALL_SIGN(sys_fsync),
+ SYSCALL_SIGN(sys_fsync), /* 155 */
SYSCALL_SIGN(sys_clock_nanosleep),
SYSCALL_SIGN(sys_timer_create),
SYSCALL_SIGN(sys_timer_delete),
SYSCALL_SIGN(sys_timer_settime),
- SYSCALL_SIGN(sys_timer_gettime),
+ SYSCALL_SIGN(sys_timer_gettime), /* 160 */
SYSCALL_SIGN(sys_timer_getoverrun),
SYSCALL_SIGN(sys_mq_open),
SYSCALL_SIGN(sys_mq_unlink),
diff --git a/components/lwp/lwp_user_mm.c b/components/lwp/lwp_user_mm.c
index 97bfdc02b3..df9231bdcd 100644
--- a/components/lwp/lwp_user_mm.c
+++ b/components/lwp/lwp_user_mm.c
@@ -14,208 +14,284 @@
#include <rtthread.h>
#include <rthw.h>
+#include <string.h>
#ifdef ARCH_MM_MMU
-#include <mmu.h>
-#include <page.h>
-#include <lwp_mm_area.h>
-#include <lwp_user_mm.h>
+#include <lwp.h>
#include <lwp_arch.h>
#include <lwp_mm.h>
+#include <lwp_user_mm.h>
+
+#include <mm_aspace.h>
+#include <mm_fault.h>
+#include <mm_flag.h>
+#include <mm_page.h>
+#include <mmu.h>
+#include <page.h>
+
+#define DBG_TAG "LwP"
+#define DBG_LVL DBG_LOG
+#include <rtdbg.h>
-int lwp_user_space_init(struct rt_lwp *lwp)
+static void _init_lwp_objs(struct rt_lwp_objs *lwp_objs, rt_aspace_t aspace);
+
+int lwp_user_space_init(struct rt_lwp *lwp, rt_bool_t is_fork)
{
- return arch_user_space_init(lwp);
+ int err = -RT_ENOMEM;
+ lwp->lwp_obj = rt_malloc(sizeof(struct rt_lwp_objs));
+ _init_lwp_objs(lwp->lwp_obj, lwp->aspace);
+ if (lwp->lwp_obj)
+ {
+ err = arch_user_space_init(lwp);
+ if (!is_fork && err == RT_EOK)
+ {
+ void *addr = (void *)USER_STACK_VSTART;
+ err = rt_aspace_map(lwp->aspace, &addr,
+ USER_STACK_VEND - USER_STACK_VSTART,
+ MMU_MAP_U_RWCB, 0, &lwp->lwp_obj->mem_obj, 0);
+ }
+ }
+ return err;
}
-#ifdef LWP_ENABLE_ASID
-void rt_hw_mmu_switch(void *mtable, unsigned int pid, unsigned int asid);
-#else
-void rt_hw_mmu_switch(void *mtable);
-#endif
-void *rt_hw_mmu_tbl_get(void);
-void lwp_mmu_switch(struct rt_thread *thread)
+void lwp_aspace_switch(struct rt_thread *thread)
{
- struct rt_lwp *l = RT_NULL;
- void *pre_mmu_table = RT_NULL, *new_mmu_table = RT_NULL;
+ struct rt_lwp *lwp = RT_NULL;
+ rt_aspace_t aspace;
+ void *from_tbl;
if (thread->lwp)
{
- l = (struct rt_lwp *)thread->lwp;
- new_mmu_table = (void *)((char *)l->mmu_info.vtable + l->mmu_info.pv_off);
+ lwp = (struct rt_lwp *)thread->lwp;
+ aspace = lwp->aspace;
}
else
- {
- new_mmu_table = arch_kernel_mmu_table_get();
- }
+ aspace = &rt_kernel_space;
- pre_mmu_table = rt_hw_mmu_tbl_get();
- if (pre_mmu_table != new_mmu_table)
+ from_tbl = rt_hw_mmu_tbl_get();
+ if (aspace->page_table != from_tbl)
{
-#ifdef LWP_ENABLE_ASID
- rt_hw_mmu_switch(new_mmu_table, l ? l->pid : 0, arch_get_asid(l));
-#else
- rt_hw_mmu_switch(new_mmu_table);
-#endif
+ rt_hw_aspace_switch(aspace);
}
}
-static void unmap_range(struct rt_lwp *lwp, void *addr, size_t size, int pa_need_free)
+void lwp_unmap_user_space(struct rt_lwp *lwp)
{
- void *va = RT_NULL, *pa = RT_NULL;
- int i = 0;
+ rt_free(lwp->lwp_obj);
+ rt_aspace_delete(lwp->aspace);
+ arch_user_space_vtable_free(lwp);
+}
- for (va = addr, i = 0; i < size; va = (void *)((char *)va + ARCH_PAGE_SIZE), i += ARCH_PAGE_SIZE)
+static const char *user_get_name(rt_varea_t varea)
+{
+ char *name;
+ if (varea->flag & MMF_TEXT)
{
- pa = rt_hw_mmu_v2p(&lwp->mmu_info, va);
- if (pa)
+ name = "user.text";
+ }
+ else
+ {
+ if (varea->start == (void *)USER_STACK_VSTART)
{
- rt_hw_mmu_unmap(&lwp->mmu_info, va, ARCH_PAGE_SIZE);
- if (pa_need_free)
- {
- rt_pages_free((void *)((char *)pa - PV_OFFSET), 0);
- }
+ name = "user.stack";
+ }
+ else if (varea->start >= (void *)USER_HEAP_VADDR &&
+ varea->start < (void *)USER_HEAP_VEND)
+ {
+ name = "user.heap";
+ }
+ else
+ {
+ name = "user.data";
}
}
+ return name;
}
-void lwp_unmap_user_space(struct rt_lwp *lwp)
+static void _user_do_page_fault(struct rt_varea *varea,
+ struct rt_mm_fault_msg *msg)
{
- struct lwp_avl_struct *node = RT_NULL;
+ struct rt_lwp_objs *lwp_objs;
+ lwp_objs = rt_container_of(varea->mem_obj, struct rt_lwp_objs, mem_obj);
+ void *vaddr = ARCH_MAP_FAILED;
- while ((node = lwp_map_find_first(lwp->map_area)) != 0)
+ if (lwp_objs->source)
{
- struct rt_mm_area_struct *ma = (struct rt_mm_area_struct *)node->data;
- int pa_need_free = 0;
-
- RT_ASSERT(ma->type < MM_AREA_TYPE_UNKNOW);
+ void *paddr = rt_hw_mmu_v2p(lwp_objs->source, msg->vaddr);
+ if (paddr != ARCH_MAP_FAILED)
+ {
+ vaddr = paddr - PV_OFFSET;
- switch (ma->type)
+ if (!(varea->flag & MMF_TEXT))
+ {
+ void *cp = rt_pages_alloc(0);
+ if (cp)
+ {
+ memcpy(cp, vaddr, ARCH_PAGE_SIZE);
+ rt_varea_insert_page(varea, cp);
+ msg->response.status = MM_FAULT_STATUS_OK;
+ msg->response.vaddr = cp;
+ msg->response.size = ARCH_PAGE_SIZE;
+ }
+ else
+ {
+ LOG_W("%s: page alloc failed at %p", __func__,
+ varea->start);
+ }
+ }
+ else
+ {
+ rt_page_t page = rt_page_addr2page(vaddr);
+ page->ref_cnt += 1;
+ rt_varea_insert_page(varea, vaddr);
+ msg->response.status = MM_FAULT_STATUS_OK;
+ msg->response.vaddr = vaddr;
+ msg->response.size = ARCH_PAGE_SIZE;
+ }
+ }
+ else if (!(varea->flag & MMF_TEXT))
{
- case MM_AREA_TYPE_DATA:
- case MM_AREA_TYPE_TEXT:
- pa_need_free = 1;
- break;
- case MM_AREA_TYPE_SHM:
- lwp_shm_ref_dec(lwp, (void *)ma->addr);
- break;
+ /* if data segment not exist in source do a fallback */
+ rt_mm_dummy_mapper.on_page_fault(varea, msg);
}
- unmap_range(lwp, (void *)ma->addr, ma->size, pa_need_free);
- lwp_map_area_remove(&lwp->map_area, ma->addr);
}
+ else /* if (!lwp_objs->source), no aspace as source data */
+ {
+ rt_mm_dummy_mapper.on_page_fault(varea, msg);
+ }
+}
- arch_user_space_vtable_free(lwp);
+static void _init_lwp_objs(struct rt_lwp_objs *lwp_objs, rt_aspace_t aspace)
+{
+ lwp_objs->source = NULL;
+ lwp_objs->mem_obj.get_name = user_get_name;
+ lwp_objs->mem_obj.hint_free = NULL;
+ lwp_objs->mem_obj.on_page_fault = _user_do_page_fault;
+ lwp_objs->mem_obj.on_page_offload = rt_mm_dummy_mapper.on_page_offload;
+ lwp_objs->mem_obj.on_varea_open = rt_mm_dummy_mapper.on_varea_open;
+ lwp_objs->mem_obj.on_varea_close = rt_mm_dummy_mapper.on_varea_close;
}
-static void *_lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, int text)
+static void *_lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size,
+ int text)
{
void *va = RT_NULL;
int ret = 0;
- rt_mmu_info *m_info = &lwp->mmu_info;
- int area_type;
+ size_t flags = MMF_PREFETCH;
+ if (text)
+ flags |= MMF_TEXT;
- va = rt_hw_mmu_map_auto(m_info, map_va, map_size, MMU_MAP_U_RWCB);
- if (!va)
- {
- return 0;
- }
+ rt_mem_obj_t mem_obj = &lwp->lwp_obj->mem_obj;
+ va = map_va ? map_va : ARCH_MAP_FAILED;
- area_type = text ? MM_AREA_TYPE_TEXT : MM_AREA_TYPE_DATA;
- ret = lwp_map_area_insert(&lwp->map_area, (size_t)va, map_size, area_type);
- if (ret != 0)
+ ret = rt_aspace_map(lwp->aspace, &va, map_size, MMU_MAP_U_RWCB, flags,
+ mem_obj, 0);
+ if (ret != RT_EOK)
{
- unmap_range(lwp, va, map_size, 1);
- return 0;
+ va = RT_NULL;
+ LOG_I("lwp_map_user: failed to map %lx with size %lx", map_va,
+ map_size);
}
+
return va;
}
int lwp_unmap_user(struct rt_lwp *lwp, void *va)
{
- struct lwp_avl_struct *ma_avl_node = RT_NULL;
- struct rt_mm_area_struct *ma = RT_NULL;
- int pa_need_free = 0;
+ int err;
+ err = rt_aspace_unmap(lwp->aspace, va, 1);
+ return err;
+}
- rt_mm_lock();
- va = (void *)((size_t)va & ~ARCH_PAGE_MASK);
- ma_avl_node = lwp_map_find(lwp->map_area, (size_t)va);
- if (!ma_avl_node)
+static void _dup_varea(rt_varea_t varea, struct rt_lwp *src_lwp,
+ rt_aspace_t dst)
+{
+ void *vaddr = varea->start;
+ void *vend = vaddr + varea->size;
+ if (vaddr < (void *)USER_STACK_VSTART || vaddr >= (void *)USER_STACK_VEND)
{
- rt_mm_unlock();
- return -1;
+ while (vaddr != vend)
+ {
+ void *paddr;
+ paddr = lwp_v2p(src_lwp, vaddr);
+ if (paddr != ARCH_MAP_FAILED)
+ {
+ rt_aspace_load_page(dst, vaddr, 1);
+ }
+ vaddr += ARCH_PAGE_SIZE;
+ }
}
- ma = (struct rt_mm_area_struct *)ma_avl_node->data;
-
- RT_ASSERT(ma->type < MM_AREA_TYPE_UNKNOW);
- if ((ma->type == MM_AREA_TYPE_DATA) || (ma->type == MM_AREA_TYPE_TEXT))
+ else
{
- pa_need_free = 1;
+ while (vaddr != vend)
+ {
+ vend -= ARCH_PAGE_SIZE;
+ void *paddr;
+ paddr = lwp_v2p(src_lwp, vend);
+ if (paddr != ARCH_MAP_FAILED)
+ {
+ rt_aspace_load_page(dst, vend, 1);
+ }
+ else
+ {
+ break;
+ }
+ }
}
- unmap_range(lwp, (void *)ma->addr, ma->size, pa_need_free);
- lwp_map_area_remove(&lwp->map_area, (size_t)va);
- rt_mm_unlock();
- return 0;
}
-int lwp_dup_user(struct lwp_avl_struct *ptree, void *arg)
+int lwp_dup_user(rt_varea_t varea, void *arg)
{
+ int err;
struct rt_lwp *self_lwp = lwp_self();
struct rt_lwp *new_lwp = (struct rt_lwp *)arg;
- struct rt_mm_area_struct *ma = (struct rt_mm_area_struct *)ptree->data;
+
void *pa = RT_NULL;
void *va = RT_NULL;
+ rt_mem_obj_t mem_obj = varea->mem_obj;
- switch (ma->type)
+ if (!mem_obj)
{
- case MM_AREA_TYPE_PHY:
- pa = rt_hw_mmu_v2p(&self_lwp->mmu_info, (void *)ma->addr);
- va = lwp_map_user_type(new_lwp, (void *)ma->addr, pa, ma->size, 0, MM_AREA_TYPE_PHY);
- break;
- case MM_AREA_TYPE_PHY_CACHED:
- pa = rt_hw_mmu_v2p(&self_lwp->mmu_info, (void *)ma->addr);
- va = lwp_map_user_type(new_lwp, (void *)ma->addr, pa, ma->size, 0, MM_AREA_TYPE_PHY_CACHED);
- break;
- case MM_AREA_TYPE_SHM:
- va = (void *)ma->addr;
- if (lwp_shm_ref_inc(self_lwp, va) > 0)
- {
- pa = rt_hw_mmu_v2p(&self_lwp->mmu_info, va);
- va = lwp_map_user_type(new_lwp, va, pa, ma->size, 1, MM_AREA_TYPE_SHM);
- }
- break;
- case MM_AREA_TYPE_DATA:
- va = lwp_map_user(new_lwp, (void *)ma->addr, ma->size, 0);
- if (va == (void *)ma->addr)
- {
- lwp_data_put(&new_lwp->mmu_info, va, va, ma->size);
- }
- break;
- case MM_AREA_TYPE_TEXT:
+ /* duplicate a physical mapping */
+ pa = lwp_v2p(self_lwp, (void *)varea->start);
+ RT_ASSERT(pa != ARCH_MAP_FAILED);
+ struct rt_mm_va_hint hint = {.flags = MMF_MAP_FIXED,
+ .limit_range_size = new_lwp->aspace->size,
+ .limit_start = new_lwp->aspace->start,
+ .prefer = varea->start,
+ .map_size = varea->size};
+ err = rt_aspace_map_phy(new_lwp->aspace, &hint, varea->attr,
+ MM_PA_TO_OFF(pa), &va);
+ if (err != RT_EOK)
+ {
+ LOG_W("%s: aspace map failed at %p with size %p", __func__,
+ varea->start, varea->size);
+ }
+ }
+ else
+ {
+ /* duplicate a mem_obj backing mapping */
+ va = varea->start;
+ err = rt_aspace_map(new_lwp->aspace, &va, varea->size, varea->attr,
+ varea->flag, &new_lwp->lwp_obj->mem_obj,
+ varea->offset);
+ if (err != RT_EOK)
+ {
+ LOG_W("%s: aspace map failed at %p with size %p", __func__,
+ varea->start, varea->size);
+ }
+ else
+ {
+ /* loading page frames for !MMF_PREFETCH varea */
+ if (!(varea->flag & MMF_PREFETCH))
{
- char *addr = (char *)ma->addr;
- size_t size = ma->size;
-
- while (size)
- {
- pa = rt_hw_mmu_v2p(&self_lwp->mmu_info, (void *)addr);
- rt_page_ref_inc((char *)pa - self_lwp->mmu_info.pv_off, 0);
- va = lwp_map_user_type(new_lwp, addr, pa, ARCH_PAGE_SIZE, 1, MM_AREA_TYPE_TEXT);
- if (va != addr)
- {
- return -1;
- }
- addr += ARCH_PAGE_SIZE;
- size -= ARCH_PAGE_SIZE;
- }
- va = (void *)ma->addr;
+ _dup_varea(varea, self_lwp, new_lwp->aspace);
}
- break;
- default:
- RT_ASSERT(0);
- break;
+ }
}
- if (va != (void *)ma->addr)
+
+ if (va != (void *)varea->start)
{
return -1;
}
@@ -227,11 +303,6 @@ int lwp_unmap_user_phy(struct rt_lwp *lwp, void *va)
return lwp_unmap_user(lwp, va);
}
-int lwp_unmap_user_type(struct rt_lwp *lwp, void *va)
-{
- return lwp_unmap_user(lwp, va);
-}
-
void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, int text)
{
void *ret = RT_NULL;
@@ -246,9 +317,8 @@ void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, int text)
map_size &= ~ARCH_PAGE_MASK;
map_va = (void *)((size_t)map_va & ~ARCH_PAGE_MASK);
- rt_mm_lock();
ret = _lwp_map_user(lwp, map_va, map_size, text);
- rt_mm_unlock();
+
if (ret)
{
ret = (void *)((char *)ret + offset);
@@ -256,42 +326,11 @@ void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, int text)
return ret;
}
-static void *_lwp_map_user_type(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t map_size, int cached, int type)
+void *lwp_map_user_phy(struct rt_lwp *lwp, void *map_va, void *map_pa,
+ size_t map_size, int cached)
{
- void *va = RT_NULL;
- rt_mmu_info *m_info = &lwp->mmu_info;
- size_t attr = 0;
- int ret = 0;
-
- if (cached)
- {
- attr = MMU_MAP_U_RWCB;
- if (type == MM_AREA_TYPE_PHY)
- {
- type = MM_AREA_TYPE_PHY_CACHED;
- }
- }
- else
- {
- attr = MMU_MAP_U_RW;
- }
-
- va = rt_hw_mmu_map(m_info, map_va, map_pa, map_size, attr);
- if (va)
- {
- ret = lwp_map_area_insert(&lwp->map_area, (size_t)va, map_size, type);
- if (ret != 0)
- {
- unmap_range(lwp, va, map_size, 0);
- return 0;
- }
- }
- return va;
-}
-
-void *lwp_map_user_type(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t map_size, int cached, int type)
-{
- void *ret = RT_NULL;
+ int err;
+ void *va;
size_t offset = 0;
if (!map_size)
@@ -300,7 +339,8 @@ void *lwp_map_user_type(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t m
}
if (map_va)
{
- if (((size_t)map_va & ARCH_PAGE_MASK) != ((size_t)map_pa & ARCH_PAGE_MASK))
+ if (((size_t)map_va & ARCH_PAGE_MASK) !=
+ ((size_t)map_pa & ARCH_PAGE_MASK))
{
return 0;
}
@@ -310,19 +350,25 @@ void *lwp_map_user_type(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t m
map_size &= ~ARCH_PAGE_MASK;
map_pa = (void *)((size_t)map_pa & ~ARCH_PAGE_MASK);
- rt_mm_lock();
- ret = _lwp_map_user_type(lwp, map_va, map_pa, map_size, cached, type);
- rt_mm_unlock();
- if (ret)
+ if (map_va == RT_NULL)
+ map_va = ARCH_MAP_FAILED;
+
+ struct rt_mm_va_hint hint = {.flags = MMF_MAP_FIXED,
+ .limit_range_size = lwp->aspace->size,
+ .limit_start = lwp->aspace->start,
+ .prefer = map_va,
+ .map_size = map_size};
+ rt_size_t attr = cached ? MMU_MAP_U_RWCB : MMU_MAP_U_RW;
+
+ err =
+ rt_aspace_map_phy(lwp->aspace, &hint, attr, MM_PA_TO_OFF(map_pa), &va);
+ if (err != RT_EOK)
{
- ret = (void *)((char *)ret + offset);
+ va = RT_NULL;
+ LOG_W("%s", __func__);
}
- return ret;
-}
-void *lwp_map_user_phy(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t map_size, int cached)
-{
- return lwp_map_user_type(lwp, map_va, map_pa, map_size, cached, MM_AREA_TYPE_PHY);
+ return va + offset;
}
rt_base_t lwp_brk(void *addr)
@@ -344,7 +390,8 @@ rt_base_t lwp_brk(void *addr)
if ((size_t)addr <= USER_HEAP_VEND)
{
- size = (((size_t)addr - lwp->end_heap) + ARCH_PAGE_SIZE - 1) & ~ARCH_PAGE_MASK;
+ size = (((size_t)addr - lwp->end_heap) + ARCH_PAGE_SIZE - 1) &
+ ~ARCH_PAGE_MASK;
va = lwp_map_user(lwp, (void *)lwp->end_heap, size, 0);
}
if (va)
@@ -357,18 +404,17 @@ rt_base_t lwp_brk(void *addr)
return ret;
}
-#define MAP_ANONYMOUS 0x20
+#define MAP_ANONYMOUS 0x20
-void* lwp_mmap2(void *addr, size_t length, int prot,
- int flags, int fd, off_t pgoffset)
+void *lwp_mmap2(void *addr, size_t length, int prot, int flags, int fd,
+ off_t pgoffset)
{
void *ret = (void *)-1;
if (fd == -1)
{
- rt_mm_lock();
+
ret = lwp_map_user(lwp_self(), addr, length, 0);
- rt_mm_unlock();
if (ret)
{
@@ -396,7 +442,7 @@ void* lwp_mmap2(void *addr, size_t length, int prot,
mmap2.prot = prot;
mmap2.flags = flags;
mmap2.pgoffset = pgoffset;
- mmap2.ret = (void*) -1;
+ mmap2.ret = (void *)-1;
if (dfs_file_mmap2(d, &mmap2) == 0)
{
@@ -422,7 +468,6 @@ int lwp_munmap(void *addr)
size_t lwp_get_from_user(void *dst, void *src, size_t size)
{
struct rt_lwp *lwp = RT_NULL;
- rt_mmu_info *m_info = RT_NULL;
/* check src */
@@ -444,15 +489,13 @@ size_t lwp_get_from_user(void *dst, void *src, size_t size)
{
return 0;
}
- m_info = &lwp->mmu_info;
- return lwp_data_get(m_info, dst, src, size);
+ return lwp_data_get(lwp, dst, src, size);
}
size_t lwp_put_to_user(void *dst, void *src, size_t size)
{
struct rt_lwp *lwp = RT_NULL;
- rt_mmu_info *m_info = RT_NULL;
/* check dst */
if (dst < (void *)USER_VADDR_START)
@@ -473,8 +516,8 @@ size_t lwp_put_to_user(void *dst, void *src, size_t size)
{
return 0;
}
- m_info = &lwp->mmu_info;
- return lwp_data_put(m_info, dst, src, size);
+
+ return lwp_data_put(lwp, dst, src, size);
}
int lwp_user_accessable(void *addr, size_t size)
@@ -482,7 +525,6 @@ int lwp_user_accessable(void *addr, size_t size)
void *addr_start = RT_NULL, *addr_end = RT_NULL, *next_page = RT_NULL;
void *tmp_addr = RT_NULL;
struct rt_lwp *lwp = lwp_self();
- rt_mmu_info *mmu_info = RT_NULL;
if (!lwp)
{
@@ -496,7 +538,7 @@ int lwp_user_accessable(void *addr, size_t size)
addr_end = (void *)((char *)addr + size);
#ifdef ARCH_RISCV64
- if(addr_start < (void *)USER_VADDR_START)
+ if (addr_start < (void *)USER_VADDR_START)
{
return 0;
}
@@ -511,8 +553,8 @@ int lwp_user_accessable(void *addr, size_t size)
}
#endif
- mmu_info = &lwp->mmu_info;
- next_page = (void *)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
+ next_page =
+ (void *)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
do
{
size_t len = (char *)next_page - (char *)addr_start;
@@ -521,7 +563,7 @@ int lwp_user_accessable(void *addr, size_t size)
{
len = size;
}
- tmp_addr = rt_hw_mmu_v2p(mmu_info, addr_start);
+ tmp_addr = lwp_v2p(lwp, addr_start);
if (!tmp_addr)
{
return 0;
@@ -534,7 +576,7 @@ int lwp_user_accessable(void *addr, size_t size)
}
/* src is in mmu_info space, dst is in current thread space */
-size_t lwp_data_get(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
+size_t lwp_data_get(struct rt_lwp *lwp, void *dst, void *src, size_t size)
{
size_t copy_len = 0;
void *addr_start = RT_NULL, *addr_end = RT_NULL, *next_page = RT_NULL;
@@ -547,7 +589,8 @@ size_t lwp_data_get(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
tmp_dst = dst;
addr_start = src;
addr_end = (void *)((char *)src + size);
- next_page = (void *)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
+ next_page =
+ (void *)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
do
{
size_t len = (char *)next_page - (char *)addr_start;
@@ -556,7 +599,7 @@ size_t lwp_data_get(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
{
len = size;
}
- tmp_src = rt_hw_mmu_v2p(mmu_info, addr_start);
+ tmp_src = lwp_v2p(lwp, addr_start);
if (!tmp_src)
{
break;
@@ -572,8 +615,8 @@ size_t lwp_data_get(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
return copy_len;
}
-/* dst is in mmu_info space, src is in current thread space */
-size_t lwp_data_put(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
+/* dst is in kernel space, src is in current thread space */
+size_t lwp_data_put(struct rt_lwp *lwp, void *dst, void *src, size_t size)
{
size_t copy_len = 0;
void *addr_start = RT_NULL, *addr_end = RT_NULL, *next_page = RT_NULL;
@@ -586,7 +629,8 @@ size_t lwp_data_put(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
tmp_src = src;
addr_start = dst;
addr_end = (void *)((char *)dst + size);
- next_page = (void *)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
+ next_page =
+ (void *)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
do
{
size_t len = (char *)next_page - (char *)addr_start;
@@ -595,7 +639,7 @@ size_t lwp_data_put(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
{
len = size;
}
- tmp_dst = rt_hw_mmu_v2p(mmu_info, addr_start);
+ tmp_dst = lwp_v2p(lwp, addr_start);
if (!tmp_dst)
{
break;
@@ -611,13 +655,4 @@ size_t lwp_data_put(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
return copy_len;
}
-void lwp_data_cache_flush(rt_mmu_info *mmu_info, void *vaddr, size_t size)
-{
- void *paddr = RT_NULL;
-
- paddr = rt_hw_mmu_v2p(mmu_info, vaddr);
- paddr = (void *)((char *)paddr - PV_OFFSET);
-
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, paddr, size);
-}
#endif
diff --git a/components/lwp/lwp_user_mm.h b/components/lwp/lwp_user_mm.h
index a85173100e..c057f23b88 100644
--- a/components/lwp/lwp_user_mm.h
+++ b/components/lwp/lwp_user_mm.h
@@ -16,24 +16,24 @@
#ifdef ARCH_MM_MMU
#include <lwp.h>
-#include <lwp_mm_area.h>
+#include <mmu.h>
+#include <mm_aspace.h>
+#include <mm_fault.h>
+#include <mm_page.h>
#ifdef __cplusplus
extern "C" {
#endif
-int lwp_user_space_init(struct rt_lwp *lwp);
+int lwp_user_space_init(struct rt_lwp *lwp, rt_bool_t is_fork);
void lwp_unmap_user_space(struct rt_lwp *lwp);
int lwp_unmap_user(struct rt_lwp *lwp, void *va);
-void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, int text);
+void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, rt_bool_t text);
-void *lwp_map_user_phy(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t map_size, int cached);
+void *lwp_map_user_phy(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t map_size, rt_bool_t cached);
int lwp_unmap_user_phy(struct rt_lwp *lwp, void *va);
-void *lwp_map_user_type(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t map_size, int cached, int type);
-int lwp_unmap_user_type(struct rt_lwp *lwp, void *va);
-
rt_base_t lwp_brk(void *addr);
void* lwp_mmap2(void *addr, size_t length, int prot, int flags, int fd, off_t pgoffset);
int lwp_munmap(void *addr);
@@ -42,9 +42,22 @@ size_t lwp_get_from_user(void *dst, void *src, size_t size);
size_t lwp_put_to_user(void *dst, void *src, size_t size);
int lwp_user_accessable(void *addr, size_t size);
-size_t lwp_data_get(rt_mmu_info *mmu_info, void *dst, void *src, size_t size);
-size_t lwp_data_put(rt_mmu_info *mmu_info, void *dst, void *src, size_t size);
-void lwp_data_cache_flush(rt_mmu_info *mmu_info, void *vaddr, size_t size);
+size_t lwp_data_get(struct rt_lwp *lwp, void *dst, void *src, size_t size);
+size_t lwp_data_put(struct rt_lwp *lwp, void *dst, void *src, size_t size);
+void lwp_data_cache_flush(struct rt_lwp *lwp, void *vaddr, size_t size);
+
+static inline void *_lwp_v2p(struct rt_lwp *lwp, void *vaddr)
+{
+ return rt_hw_mmu_v2p(lwp->aspace, vaddr);
+}
+
+static inline void *lwp_v2p(struct rt_lwp *lwp, void *vaddr)
+{
+ RD_LOCK(lwp->aspace);
+ void *paddr = _lwp_v2p(lwp, vaddr);
+ RD_UNLOCK(lwp->aspace);
+ return paddr;
+}
#ifdef __cplusplus
}
diff --git a/components/lwp/page.c b/components/lwp/page.c
deleted file mode 100644
index e133d8fb10..0000000000
--- a/components/lwp/page.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright (c) 2006-2019, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2019-11-01 Jesven The first version
- */
-#include <stdint.h>
-
-#include <rthw.h>
-#include <rtthread.h>
-
-#ifdef ARCH_MM_MMU
-
-#include <page.h>
-#include <mmu.h>
-
-#define ARCH_PAGE_LIST_SIZE (ARCH_ADDRESS_WIDTH_BITS - ARCH_PAGE_SHIFT)
-
-#define DBG_TAG "PAGE"
-#define DBG_LVL DBG_WARNING
-#include <rtdbg.h>
-
-struct page
-{
- struct page *next; /* same level next */
- struct page *pre; /* same level pre */
- uint32_t size_bits; /* if is ARCH_ADDRESS_WIDTH_BITS, means not free */
- int ref_cnt; /* page group ref count */
-};
-
-static struct page* page_start;
-static void* page_addr;
-static size_t page_nr;
-
-static struct page *page_list[ARCH_PAGE_LIST_SIZE];
-
-rt_weak int rt_hw_clz(size_t n)
-{
- int bits = sizeof(size_t) * 8;
-
- n |= (n >> 1);
- n |= (n >> 2);
- n |= (n >> 4);
- n |= (n >> 8);
- n |= (n >> 16);
-
-#ifdef ARCH_CPU_64BIT
- n |= (n >> 32);
-
- n = (n & 0x5555555555555555UL) + ((n >> 1) & 0x5555555555555555UL);
- n = (n & 0x3333333333333333UL) + ((n >> 2) & 0x3333333333333333UL);
- n = (n & 0x0707070707070707UL) + ((n >> 4) & 0x0707070707070707UL);
- n = (n & 0x000f000f000f000fUL) + ((n >> 8) & 0x000f000f000f000fUL);
- n = (n & 0x0000001f0000001fUL) + ((n >> 16) & 0x0000001f0000001fUL);
- n = (n & 0x000000000000003fUL) + ((n >> 32) & 0x000000000000003fUL);
-#else
- n = (n & 0x55555555UL) + ((n >> 1) & 0x55555555UL);
- n = (n & 0x33333333UL) + ((n >> 2) & 0x33333333UL);
- n = (n & 0x07070707UL) + ((n >> 4) & 0x07070707UL);
- n = (n & 0x000f000fUL) + ((n >> 8) & 0x000f000fUL);
- n = (n & 0x0000001fUL) + ((n >> 16) & 0x0000001fUL);
-#endif
- return bits - n;
-}
-
-rt_weak int rt_hw_ctz(size_t n)
-{
- int ret = sizeof(size_t) * 8;
-
- if (n)
- {
- ret -= (rt_hw_clz(n ^ (n - 1)) + 1);
- }
- return ret;
-}
-
-size_t rt_page_bits(size_t size)
-{
- int bit = sizeof(size_t) * 8 - rt_hw_clz(size) - 1;
-
- if ((size ^ (1UL << bit)) != 0)
- {
- bit++;
- }
- bit -= ARCH_PAGE_SHIFT;
- if (bit < 0)
- {
- bit = 0;
- }
- return bit;
-}
-
-static struct page * addr_to_page(void *addr)
-{
- size_t off;
-
- if (addr < page_addr)
- {
- return 0;
- }
- off = (size_t)((char*)addr - (char*)page_addr);
- off >>= ARCH_PAGE_SHIFT;
- if (off >= page_nr)
- {
- return 0;
- }
- return &page_start[off];
-}
-
-static void* page_to_addr(struct page* p)
-{
- if (!p)
- {
- return 0;
- }
- return (void*)((char*)page_addr + ((p - page_start) << ARCH_PAGE_SHIFT));
-}
-
-static inline struct page *buddy_get(struct page *p, uint32_t size_bits)
-{
- size_t addr;
-
- addr = (size_t)page_to_addr(p);
- addr ^= (1UL << (size_bits + ARCH_PAGE_SHIFT));
- return addr_to_page((void*)addr);
-}
-
-static void page_remove(struct page *p, uint32_t size_bits)
-{
- if (p->pre)
- {
- p->pre->next = p->next;
- }
- else
- {
- page_list[size_bits] = p->next;
- }
-
- if (p->next)
- {
- p->next->pre = p->pre;
- }
-
- p->size_bits = ARCH_ADDRESS_WIDTH_BITS;
-}
-
-static void page_insert(struct page *p, uint32_t size_bits)
-{
- p->next = page_list[size_bits];
- if (p->next)
- {
- p->next->pre = p;
- }
- p->pre = 0;
- page_list[size_bits] = p;
- p->size_bits = size_bits;
-}
-
-static void _pages_ref_inc(struct page *p, uint32_t size_bits)
-{
- struct page *page_head;
- int idx;
-
- /* find page group head */
- idx = p - page_start;
- if (idx < 0 || idx >= page_nr)
- {
- return;
- }
- idx = idx & ~((1UL << size_bits) - 1);
-
- page_head = page_start + idx;
- page_head->ref_cnt++;
-}
-
-static int _pages_ref_get(struct page *p, uint32_t size_bits)
-{
- struct page *page_head;
- int idx;
-
- /* find page group head */
- idx = p - page_start;
- if (idx < 0 || idx >= page_nr)
- {
- return 0;
- }
- idx = idx & ~((1UL << size_bits) - 1);
-
- page_head = page_start + idx;
- return page_head->ref_cnt;
-}
-
-static int _pages_free(struct page *p, uint32_t size_bits)
-{
- uint32_t level = size_bits;
- struct page *buddy;
-
- RT_ASSERT(p->ref_cnt > 0);
- RT_ASSERT(p->size_bits == ARCH_ADDRESS_WIDTH_BITS);
-
- p->ref_cnt--;
- if (p->ref_cnt != 0)
- {
- return 0;
- }
-
- while (level < ARCH_PAGE_LIST_SIZE)
- {
- buddy = buddy_get(p, level);
- if (buddy && buddy->size_bits == level)
- {
- page_remove(buddy, level);
- p = (p < buddy) ? p : buddy;
- level++;
- }
- else
- {
- break;
- }
- }
- page_insert(p, level);
- return 1;
-}
-
-static struct page *_pages_alloc(uint32_t size_bits)
-{
- struct page *p;
-
- if (page_list[size_bits])
- {
- p = page_list[size_bits];
- page_remove(p, size_bits);
- }
- else
- {
- uint32_t level;
-
- for (level = size_bits + 1; level < ARCH_PAGE_LIST_SIZE; level++)
- {
- if (page_list[level])
- {
- break;
- }
- }
- if (level == ARCH_PAGE_LIST_SIZE)
- {
- return 0;
- }
-
- p = page_list[level];
- page_remove(p, level);
- while (level > size_bits)
- {
- page_insert(p, level - 1);
- p = buddy_get(p, level - 1);
- level--;
- }
- }
- p->size_bits = ARCH_ADDRESS_WIDTH_BITS;
- p->ref_cnt = 1;
- return p;
-}
-
-int rt_page_ref_get(void *addr, uint32_t size_bits)
-{
- struct page *p;
- rt_base_t level;
- int ref;
-
- p = addr_to_page(addr);
- level = rt_hw_interrupt_disable();
- ref = _pages_ref_get(p, size_bits);
- rt_hw_interrupt_enable(level);
- return ref;
-}
-
-void rt_page_ref_inc(void *addr, uint32_t size_bits)
-{
- struct page *p;
- rt_base_t level;
-
- p = addr_to_page(addr);
- level = rt_hw_interrupt_disable();
- _pages_ref_inc(p, size_bits);
- rt_hw_interrupt_enable(level);
-}
-
-void *rt_pages_alloc(uint32_t size_bits)
-{
- struct page *p;
- rt_base_t level;
-
- level = rt_hw_interrupt_disable();
- p = _pages_alloc(size_bits);
- rt_hw_interrupt_enable(level);
- return page_to_addr(p);
-}
-
-int rt_pages_free(void *addr, uint32_t size_bits)
-{
- struct page *p;
- int real_free = 0;
-
- p = addr_to_page(addr);
- if (p)
- {
- rt_base_t level;
- level = rt_hw_interrupt_disable();
- real_free = _pages_free(p, size_bits);
- rt_hw_interrupt_enable(level);
- }
- return real_free;
-}
-
-void list_page(void)
-{
- int i;
- size_t total = 0;
-
- rt_base_t level;
- level = rt_hw_interrupt_disable();
-
- for (i = 0; i < ARCH_PAGE_LIST_SIZE; i++)
- {
- struct page *p = page_list[i];
-
- rt_kprintf("level %d ", i);
-
- while (p)
- {
- total += (1UL << i);
- rt_kprintf("[0x%08p]", page_to_addr(p));
- p = p->next;
- }
- rt_kprintf("\n");
- }
- rt_hw_interrupt_enable(level);
- rt_kprintf("free pages is %08x\n", total);
- rt_kprintf("-------------------------------\n");
-}
-MSH_CMD_EXPORT(list_page, show page info);
-
-void rt_page_get_info(size_t *total_nr, size_t *free_nr)
-{
- int i;
- size_t total_free = 0;
- rt_base_t level;
-
- level = rt_hw_interrupt_disable();
- for (i = 0; i < ARCH_PAGE_LIST_SIZE; i++)
- {
- struct page *p = page_list[i];
-
- while (p)
- {
- total_free += (1UL << i);
- p = p->next;
- }
- }
- rt_hw_interrupt_enable(level);
- *total_nr = page_nr;
- *free_nr = total_free;
-}
-
-void rt_page_init(rt_region_t reg)
-{
- int i;
-
- LOG_D("split 0x%08x 0x%08x\n", reg.start, reg.end);
-
- reg.start += ARCH_PAGE_MASK;
- reg.start &= ~ARCH_PAGE_MASK;
-
- reg.end &= ~ARCH_PAGE_MASK;
-
- {
- int nr = ARCH_PAGE_SIZE / sizeof(struct page);
- int total = (reg.end - reg.start) >> ARCH_PAGE_SHIFT;
- int mnr = (total + nr) / (nr + 1);
-
- LOG_D("nr = 0x%08x\n", nr);
- LOG_D("total = 0x%08x\n", total);
- LOG_D("mnr = 0x%08x\n", mnr);
-
- RT_ASSERT(mnr < total);
-
- page_start = (struct page*)reg.start;
- reg.start += (mnr << ARCH_PAGE_SHIFT);
- page_addr = (void*)reg.start;
- page_nr = (reg.end - reg.start) >> ARCH_PAGE_SHIFT;
- }
-
- LOG_D("align 0x%08x 0x%08x\n", reg.start, reg.end);
-
- /* init free list */
- for (i = 0; i < ARCH_PAGE_LIST_SIZE; i++)
- {
- page_list[i] = 0;
- }
-
- /* add pages to free list */
- while (reg.start != reg.end)
- {
- struct page *p;
- int align_bits;
- int size_bits;
-
- size_bits = ARCH_ADDRESS_WIDTH_BITS - 1 - rt_hw_clz(reg.end - reg.start);
- align_bits = rt_hw_ctz(reg.start);
- if (align_bits < size_bits)
- {
- size_bits = align_bits;
- }
- p = addr_to_page((void*)reg.start);
- p->size_bits = ARCH_ADDRESS_WIDTH_BITS;
- p->ref_cnt = 1;
- _pages_free(p, size_bits - ARCH_PAGE_SHIFT);
- reg.start += (1UL << size_bits);
- }
-}
-#endif
diff --git a/components/lwp/page.h b/components/lwp/page.h
index 242cbdfa2d..63324f988c 100644
--- a/components/lwp/page.h
+++ b/components/lwp/page.h
@@ -11,30 +11,6 @@
#ifndef __PAGE_H__
#define __PAGE_H__
-#ifdef ARCH_MM_MMU
-
-typedef struct tag_region
-{
- size_t start;
- size_t end;
-} rt_region_t;
-
-void rt_page_init(rt_region_t reg);
-
-void *rt_pages_alloc(uint32_t size_bits);
-
-void rt_page_ref_inc(void *addr, uint32_t size_bits);
-
-int rt_page_ref_get(void *addr, uint32_t size_bits);
-
-int rt_pages_free(void *addr, uint32_t size_bits);
-
-void rt_pageinfo_dump(void);
-
-size_t rt_page_bits(size_t size);
-
-void rt_page_get_info(size_t *total_nr, size_t *free_nr);
-
-#endif
-
+#include <mm_page.h>
#endif /*__PAGE_H__*/
+
diff --git a/components/mm/SConscript b/components/mm/SConscript
new file mode 100644
index 0000000000..d6f78ee06f
--- /dev/null
+++ b/components/mm/SConscript
@@ -0,0 +1,21 @@
+import os
+from building import *
+
+objs = []
+
+if GetDepend('ARCH_MM_MMU'):
+ cwd = GetCurrentDir()
+ src = Glob('*.c') + Glob('*_gcc.S')
+ CPPPATH = [cwd]
+
+ group = DefineGroup('mm', src, depend = [''], CPPPATH = CPPPATH)
+
+ objs = [group]
+ list = os.listdir(cwd)
+
+ for d in list:
+ path = os.path.join(cwd, d)
+ if os.path.isfile(os.path.join(path, 'SConscript')):
+ objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')
diff --git a/components/mm/avl_adpt.c b/components/mm/avl_adpt.c
new file mode 100644
index 0000000000..f89f667685
--- /dev/null
+++ b/components/mm/avl_adpt.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-11-14 WangXiaoyao the first version
+ */
+#include <rtdef.h>
+
+#include <avl.h>
+#include "avl_adpt.h"
+#include "mm_aspace.h"
+#include "mm_private.h"
+
+#define DBG_TAG "MM"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+/**
+ * @brief Adapter Layer for lwp AVL BST
+ */
+
+rt_err_t _aspace_bst_init(struct rt_aspace *aspace)
+{
+ aspace->tree.tree.root_node = AVL_ROOT;
+ return RT_EOK;
+}
+
+static int compare_overlap(void *as, void *ae, void *bs, void *be)
+{
+ LOG_D("as %lx, ae %lx, bs %lx, be %lx", as, ae, bs, be);
+ int cmp;
+ if (as > be)
+ {
+ cmp = 1;
+ }
+ else if (ae < bs)
+ {
+ cmp = -1;
+ }
+ else
+ {
+ cmp = 0;
+ }
+ LOG_D("ret %d", cmp);
+ return cmp;
+}
+
+static int compare_exceed(void *as, void *ae, void *bs, void *be)
+{
+ LOG_D("as %lx, ae %lx, bs %lx, be %lx", as, ae, bs, be);
+ int cmp;
+ if (as > bs)
+ {
+ cmp = 1;
+ }
+ else if (as < bs)
+ {
+ cmp = -1;
+ }
+ else
+ {
+ cmp = 0;
+ }
+ LOG_D("ret %d", cmp);
+ return cmp;
+}
+
+static struct rt_varea *search(struct util_avl_root *root,
+ struct _mm_range range,
+ int (*compare)(void *as, void *ae, void *bs,
+ void *be))
+{
+ struct util_avl_struct *node = root->root_node;
+ while (node)
+ {
+ rt_varea_t varea = VAREA_ENTRY(node);
+ int cmp = compare(range.start, range.end, varea->start,
+ varea->start + varea->size - 1);
+
+ if (cmp < 0)
+ {
+ node = node->avl_left;
+ }
+ else if (cmp > 0)
+ {
+ node = node->avl_right;
+ }
+ else
+ {
+ return varea;
+ }
+ }
+ return NULL;
+}
+
+struct rt_varea *_aspace_bst_search(struct rt_aspace *aspace, void *key)
+{
+ struct util_avl_root *root = &aspace->tree.tree;
+ struct _mm_range range = {key, key};
+ return search(root, range, compare_overlap);
+}
+
+rt_varea_t _aspace_bst_search_exceed(struct rt_aspace *aspace, void *start)
+{
+ struct util_avl_root *root = &aspace->tree.tree;
+ struct util_avl_struct *node = root->root_node;
+ rt_varea_t closest = NULL;
+ ptrdiff_t min_off = PTRDIFF_MAX;
+ while (node)
+ {
+ rt_varea_t varea = VAREA_ENTRY(node);
+ void *va_s = varea->start;
+ int cmp = compare_exceed(start, start, va_s, va_s);
+
+ if (cmp < 0)
+ {
+ ptrdiff_t off = va_s - start;
+ if (off < min_off)
+ {
+ min_off = off;
+ closest = varea;
+ }
+ node = node->avl_left;
+ }
+ else if (cmp > 0)
+ {
+ node = node->avl_right;
+ }
+ else
+ {
+ return varea;
+ }
+ }
+ return closest;
+}
+
+struct rt_varea *_aspace_bst_search_overlap(struct rt_aspace *aspace,
+ struct _mm_range range)
+{
+ struct util_avl_root *root = &aspace->tree.tree;
+ return search(root, range, compare_overlap);
+}
+
+void _aspace_bst_insert(struct rt_aspace *aspace, struct rt_varea *varea)
+{
+ struct util_avl_root *root = &aspace->tree.tree;
+ struct util_avl_struct *current = NULL;
+ struct util_avl_struct **next = &(root->root_node);
+ rt_ubase_t key = (rt_ubase_t)varea->start;
+
+ /* Figure out where to put new node */
+ while (*next)
+ {
+ current = *next;
+ struct rt_varea *data = VAREA_ENTRY(current);
+
+ if (key < (rt_ubase_t)data->start)
+ next = &(current->avl_left);
+ else if (key > (rt_ubase_t)data->start)
+ next = &(current->avl_right);
+ else
+ return;
+ }
+
+ /* Add new node and rebalance tree. */
+ util_avl_link(&varea->node.node, current, next);
+ util_avl_rebalance(current, root);
+ return;
+}
+
+void _aspace_bst_remove(struct rt_aspace *aspace, struct rt_varea *varea)
+{
+ struct util_avl_struct *node = &varea->node.node;
+ util_avl_remove(node, &aspace->tree.tree);
+}
diff --git a/components/mm/avl_adpt.h b/components/mm/avl_adpt.h
new file mode 100644
index 0000000000..f58c9974fb
--- /dev/null
+++ b/components/mm/avl_adpt.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-11-14 WangXiaoyao the first version
+ */
+
+#ifndef __MM_AVL_ADPT_H__
+#define __MM_AVL_ADPT_H__
+
+#include <avl.h>
+#include <rtdef.h>
+#include <rtthread.h>
+#include <stdint.h>
+
+#define VAREA_ENTRY(pnode) \
+ (pnode) \
+ ? rt_container_of(rt_container_of(pnode, struct _aspace_node, node), \
+ struct rt_varea, node) \
+ : 0
+#define ASPACE_VAREA_NEXT(pva) (VAREA_ENTRY(util_avl_next(&pva->node.node)))
+#define ASPACE_VAREA_FIRST(aspace) (VAREA_ENTRY(util_avl_first(&aspace->tree.tree)))
+
+typedef struct _aspace_node
+{
+ struct util_avl_struct node;
+} *_aspace_node_t;
+
+typedef struct _aspace_tree
+{
+ struct util_avl_root tree;
+} *_aspace_tree_t;
+
+#endif /* __MM_AVL_ADPT_H__ */
diff --git a/components/mm/mm_aspace.c b/components/mm/mm_aspace.c
new file mode 100644
index 0000000000..9bb91239e6
--- /dev/null
+++ b/components/mm/mm_aspace.c
@@ -0,0 +1,743 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-11-14 WangXiaoyao the first version
+ */
+
+/**
+ * @brief Virtual Address Space
+ */
+
+#include <rtdef.h>
+#include <rtthread.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "avl_adpt.h"
+#include "mm_aspace.h"
+#include "mm_fault.h"
+#include "mm_flag.h"
+#include "mm_page.h"
+#include "mm_private.h"
+
+#include <mmu.h>
+#include <tlb.h>
+
+#ifndef RT_USING_SMART
+#define PV_OFFSET 0
+#endif
+
+#define DBG_TAG "mm.aspace"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+static void _aspace_unmap(rt_aspace_t aspace, void *addr, rt_size_t length);
+static void *_find_free(rt_aspace_t aspace, void *prefer, rt_size_t req_size,
+ void *limit_start, rt_size_t limit_size,
+ mm_flag_t flags);
+
+struct rt_aspace rt_kernel_space;
+
+rt_varea_t _varea_create(void *start, rt_size_t size)
+{
+ rt_varea_t varea;
+ varea = (rt_varea_t)rt_malloc(sizeof(struct rt_varea));
+ if (varea)
+ {
+ varea->start = start;
+ varea->size = size;
+ }
+ return varea;
+}
+
+static inline void _varea_post_install(rt_varea_t varea, rt_aspace_t aspace,
+ rt_size_t attr, rt_size_t flags,
+ rt_mem_obj_t mem_obj, rt_size_t offset)
+{
+ varea->aspace = aspace;
+ varea->attr = attr;
+ varea->mem_obj = mem_obj;
+ varea->flag = flags;
+ varea->offset = offset;
+ varea->frames = NULL;
+
+ if (varea->mem_obj && varea->mem_obj->on_varea_open)
+ varea->mem_obj->on_varea_open(varea);
+}
+
+int _init_lock(rt_aspace_t aspace)
+{
+ MM_PGTBL_LOCK_INIT(aspace);
+ rt_mutex_init(&aspace->bst_lock, "", RT_IPC_FLAG_FIFO);
+
+ return RT_EOK;
+}
+
+rt_aspace_t rt_aspace_create(void *start, rt_size_t length, void *pgtbl)
+{
+ rt_aspace_t aspace = NULL;
+ void *page_table = pgtbl;
+
+ if (page_table)
+ {
+ aspace = (rt_aspace_t)rt_malloc(sizeof(*aspace));
+ if (aspace)
+ {
+ aspace->page_table = page_table;
+ aspace->start = start;
+ aspace->size = length;
+ if (_init_lock(aspace) != RT_EOK ||
+ _aspace_bst_init(aspace) != RT_EOK)
+ {
+ rt_free(aspace);
+ aspace = NULL;
+ }
+ }
+ }
+ return aspace;
+}
+
+rt_aspace_t rt_aspace_init(rt_aspace_t aspace, void *start, rt_size_t length,
+ void *pgtbl)
+{
+ void *page_table = pgtbl;
+ LOG_D("%s", __func__);
+
+ if (page_table)
+ {
+ aspace->page_table = page_table;
+ aspace->start = start;
+ aspace->size = length;
+ if (_init_lock(aspace) != RT_EOK || _aspace_bst_init(aspace) != RT_EOK)
+ {
+ aspace = NULL;
+ }
+ }
+ return aspace;
+}
+
+void rt_aspace_detach(rt_aspace_t aspace)
+{
+ _aspace_unmap(aspace, aspace->start, aspace->size);
+ rt_mutex_detach(&aspace->bst_lock);
+}
+
+void rt_aspace_delete(rt_aspace_t aspace)
+{
+ if (aspace)
+ {
+ rt_aspace_detach(aspace);
+ rt_free(aspace);
+ }
+}
+
+static int _do_named_map(rt_aspace_t aspace, void *vaddr, rt_size_t length,
+ rt_size_t offset, rt_size_t attr)
+{
+ int err = RT_EOK;
+
+ /* it's ensured by caller that (void*)end will not overflow */
+ void *end = vaddr + length;
+ void *phyaddr = (void *)(offset << MM_PAGE_SHIFT);
+ while (vaddr != end)
+ {
+ /* TODO try to map with huge TLB, when flag & HUGEPAGE */
+ rt_size_t pgsz = ARCH_PAGE_SIZE;
+ rt_hw_mmu_map(aspace, vaddr, phyaddr, pgsz, attr);
+ vaddr += pgsz;
+ phyaddr += pgsz;
+ }
+
+ rt_hw_tlb_invalidate_range(aspace, vaddr, length, ARCH_PAGE_SIZE);
+
+ return err;
+}
+
+rt_inline void _do_page_fault(struct rt_mm_fault_msg *msg, rt_size_t off,
+ void *vaddr, rt_mem_obj_t mem_obj,
+ rt_varea_t varea)
+{
+ msg->off = off;
+ msg->vaddr = vaddr;
+ msg->fault_op = MM_FAULT_OP_READ;
+ msg->fault_type = MM_FAULT_TYPE_PAGE_FAULT;
+ msg->response.status = -1;
+
+ mem_obj->on_page_fault(varea, msg);
+}
+
+/* allocate memory page for mapping range */
+static int _do_prefetch(rt_aspace_t aspace, rt_varea_t varea, void *start,
+ rt_size_t size)
+{
+ int err = RT_EOK;
+
+ /* it's ensured by caller that start & size ara page-aligned */
+ void *end = start + size;
+ void *vaddr = start;
+ rt_size_t off = varea->offset + ((start - varea->start) >> ARCH_PAGE_SHIFT);
+
+ while (vaddr != end)
+ {
+ /* TODO try to map with huge TLB, when flag & HUGEPAGE */
+ struct rt_mm_fault_msg msg;
+ _do_page_fault(&msg, off, vaddr, varea->mem_obj, varea);
+
+ if (msg.response.status == MM_FAULT_STATUS_OK)
+ {
+ void *store = msg.response.vaddr;
+ rt_size_t store_sz = msg.response.size;
+
+ if (store_sz + vaddr > end)
+ {
+ LOG_W("%s: too much (0x%lx) of buffer at vaddr %p is provided",
+ __func__, store_sz, vaddr);
+ break;
+ }
+
+ void *map = rt_hw_mmu_map(aspace, vaddr, store + PV_OFFSET,
+ store_sz, varea->attr);
+
+ if (!map)
+ {
+ LOG_W("%s: MMU mapping failed for va %p to %p of %lx", __func__,
+ vaddr, store + PV_OFFSET, store_sz);
+ }
+ vaddr += store_sz;
+ off += store_sz >> ARCH_PAGE_SHIFT;
+
+ rt_hw_tlb_invalidate_range(aspace, vaddr, store_sz, ARCH_PAGE_SIZE);
+ }
+ else
+ {
+ err = -RT_ENOMEM;
+ LOG_W("%s failed because no memory is provided", __func__);
+ break;
+ }
+ }
+
+ return err;
+}
+
+int _varea_install(rt_aspace_t aspace, rt_varea_t varea, rt_mm_va_hint_t hint)
+{
+ void *alloc_va;
+ int err = RT_EOK;
+
+ /**
+ * find a suitable va range.
+ * even though this is sleepable, it's still ok for startup routine
+ */
+ alloc_va =
+ _find_free(aspace, hint->prefer, hint->map_size, hint->limit_start,
+ hint->limit_range_size, hint->flags);
+
+ /* TODO try merge surrounding regions to optimize memory footprint */
+
+ if (alloc_va != ARCH_MAP_FAILED)
+ {
+ varea->start = alloc_va;
+ _aspace_bst_insert(aspace, varea);
+ }
+ else
+ {
+ err = -RT_ENOSPC;
+ }
+
+ return err;
+}
+
+static int _mm_aspace_map(rt_aspace_t aspace, rt_varea_t varea, rt_size_t attr,
+ mm_flag_t flags, rt_mem_obj_t mem_obj,
+ rt_size_t offset)
+{
+ int err = RT_EOK;
+
+ WR_LOCK(aspace);
+ struct rt_mm_va_hint hint = {.prefer = varea->start,
+ .map_size = varea->size,
+ .limit_start = aspace->start,
+ .limit_range_size = aspace->size,
+ .flags = flags};
+
+ if (mem_obj->hint_free)
+ {
+ mem_obj->hint_free(&hint);
+ }
+
+ err = _varea_install(aspace, varea, &hint);
+ WR_UNLOCK(aspace);
+
+ if (err == RT_EOK)
+ {
+ _varea_post_install(varea, aspace, attr, flags, mem_obj, offset);
+
+ if (MMF_TEST_CNTL(flags, MMF_PREFETCH))
+ {
+ err = _do_prefetch(aspace, varea, varea->start, varea->size);
+ }
+ }
+
+ return err;
+}
+
+static inline int _not_in_range(void *start, rt_size_t length,
+ void *limit_start, rt_size_t limit_size)
+{
+ /* assuming (base + length) will not overflow except (0) */
+ return start != ARCH_MAP_FAILED
+ ? ((length > (0ul - (uintptr_t)start)) || start < limit_start ||
+ (length + (rt_size_t)(start - limit_start)) > limit_size)
+ : length > limit_size;
+}
+
+static inline int _not_align(void *start, rt_size_t length, rt_size_t mask)
+{
+ return (start != ARCH_MAP_FAILED) &&
+ (((uintptr_t)start & mask) || (length & mask));
+}
+
+static inline int _not_support(rt_size_t flags)
+{
+ rt_size_t support_ops = (MMF_PREFETCH | MMF_MAP_FIXED | MMF_TEXT);
+ return flags & ~(support_ops | _MMF_ALIGN_MASK);
+}
+
+int rt_aspace_map(rt_aspace_t aspace, void **addr, rt_size_t length,
+ rt_size_t attr, mm_flag_t flags, rt_mem_obj_t mem_obj,
+ rt_size_t offset)
+{
+ /* TODO check not in atomic context: irq, spinlock, local intr disable... */
+ int err;
+ rt_varea_t varea;
+
+ if (!aspace || !addr || !mem_obj || length == 0 ||
+ _not_in_range(*addr, length, aspace->start, aspace->size))
+ {
+ err = -RT_EINVAL;
+ LOG_I("%s: Invalid input", __func__);
+ }
+ else if (_not_support(flags))
+ {
+ LOG_I("%s: no support flags 0x%p", __func__, flags);
+ err = -RT_ENOSYS;
+ }
+ else
+ {
+ varea = _varea_create(*addr, length);
+
+ if (varea)
+ {
+ err = _mm_aspace_map(aspace, varea, attr, flags, mem_obj, offset);
+ }
+ else
+ {
+ err = -RT_ENOMEM;
+ }
+ }
+
+ if (err != RT_EOK)
+ {
+ *addr = NULL;
+ }
+ else
+ {
+ *addr = varea->start;
+ }
+ return err;
+}
+
+int rt_aspace_map_static(rt_aspace_t aspace, rt_varea_t varea, void **addr,
+ rt_size_t length, rt_size_t attr, mm_flag_t flags,
+ rt_mem_obj_t mem_obj, rt_size_t offset)
+{
+ int err;
+
+ if (!aspace || !varea || !addr || !mem_obj || length == 0 ||
+ _not_in_range(*addr, length, aspace->start, aspace->size))
+ {
+ err = -RT_EINVAL;
+ LOG_W("%s: Invalid input", __func__);
+ }
+ else if (_not_support(flags))
+ {
+ LOG_W("%s: no support flags", __func__);
+ err = -RT_ENOSYS;
+ }
+ else
+ {
+ varea->size = length;
+ varea->start = *addr;
+ err = _mm_aspace_map(aspace, varea, attr, flags, mem_obj, offset);
+ }
+
+ if (err != RT_EOK)
+ {
+ *addr = NULL;
+ }
+ else
+ {
+ *addr = varea->start;
+ }
+ return err;
+}
+
+int _mm_aspace_map_phy(rt_aspace_t aspace, rt_varea_t varea,
+ rt_mm_va_hint_t hint, rt_size_t attr, rt_size_t pa_off,
+ void **ret_va)
+{
+ int err;
+ void *vaddr;
+
+ if (!aspace || !hint || !hint->limit_range_size || !hint->map_size ||
+ _not_align(hint->prefer, hint->map_size, ARCH_PAGE_MASK) ||
+ _not_in_range(hint->limit_start, hint->limit_range_size, aspace->start,
+ aspace->size) ||
+ _not_in_range(hint->prefer, hint->map_size, aspace->start,
+ aspace->size))
+ {
+ LOG_I("%s: Invalid input", __func__);
+ err = -RT_EINVAL;
+ }
+ else
+ {
+ WR_LOCK(aspace);
+ err = _varea_install(aspace, varea, hint);
+ WR_UNLOCK(aspace);
+
+ if (err == RT_EOK)
+ {
+ _varea_post_install(varea, aspace, attr, 0, NULL, pa_off);
+
+ vaddr = varea->start;
+
+ err = _do_named_map(aspace, varea->start, varea->size,
+ (rt_size_t)pa_off, attr);
+
+ if (err != RT_EOK)
+ {
+ _aspace_unmap(aspace, varea->start, varea->size);
+ rt_free(varea);
+ }
+ }
+ }
+
+ if (ret_va)
+ {
+ if (err == RT_EOK)
+ *ret_va = vaddr;
+ else
+ *ret_va = ARCH_MAP_FAILED;
+ }
+
+ return err;
+}
+
+int rt_aspace_map_phy(rt_aspace_t aspace, rt_mm_va_hint_t hint, rt_size_t attr,
+ rt_size_t pa_off, void **ret_va)
+{
+ int err;
+
+ if (hint)
+ {
+ rt_varea_t varea = _varea_create(hint->prefer, hint->map_size);
+ if (varea)
+ {
+ err = _mm_aspace_map_phy(aspace, varea, hint, attr, pa_off, ret_va);
+ if (err != RT_EOK)
+ {
+ rt_free(varea);
+ }
+ }
+ else
+ {
+ err = -RT_ENOMEM;
+ }
+ }
+ else
+ {
+ err = -RT_EINVAL;
+ }
+
+ return err;
+}
+
+int rt_aspace_map_phy_static(rt_aspace_t aspace, rt_varea_t varea,
+ rt_mm_va_hint_t hint, rt_size_t attr,
+ rt_size_t pa_off, void **ret_va)
+{
+ int err;
+
+ if (varea && hint)
+ {
+ varea->start = hint->prefer;
+ varea->size = hint->map_size;
+ hint->flags |= MMF_MAP_FIXED;
+ err = _mm_aspace_map_phy(aspace, varea, hint, attr, pa_off, ret_va);
+ }
+ else
+ {
+ err = -RT_EINVAL;
+ }
+
+ return err;
+}
+
+void _aspace_unmap(rt_aspace_t aspace, void *addr, rt_size_t length)
+{
+ struct _mm_range range = {addr, addr + length - 1};
+ rt_varea_t varea = _aspace_bst_search_overlap(aspace, range);
+ while (varea)
+ {
+ if (varea->mem_obj && varea->mem_obj->on_varea_close)
+ varea->mem_obj->on_varea_close(varea);
+
+ rt_varea_free_pages(varea);
+
+ WR_LOCK(aspace);
+ _aspace_bst_remove(aspace, varea);
+ WR_UNLOCK(aspace);
+
+ rt_hw_mmu_unmap(aspace, varea->start, varea->size);
+ rt_hw_tlb_invalidate_range(aspace, varea->start, varea->size,
+ ARCH_PAGE_SIZE);
+
+ rt_free(varea);
+ varea = _aspace_bst_search_overlap(aspace, range);
+ }
+}
+
+int rt_aspace_unmap(rt_aspace_t aspace, void *addr, rt_size_t length)
+{
+ if (!aspace)
+ {
+ LOG_I("%s: Invalid input", __func__);
+ return -RT_EINVAL;
+ }
+
+ if (_not_in_range(addr, length, aspace->start, aspace->size))
+ {
+ LOG_I("%s: %lx not in range of aspace[%lx:%lx]", __func__, addr,
+ aspace->start, aspace->start + aspace->size);
+ return -RT_EINVAL;
+ }
+
+ _aspace_unmap(aspace, addr, length);
+
+ return RT_EOK;
+}
+
+static inline void *_lower(void *a, void *b)
+{
+ return a < b ? a : b;
+}
+
+static inline void *_align(void *va, rt_ubase_t align_mask)
+{
+ return (void *)((rt_ubase_t)(va + ~align_mask) & align_mask);
+}
+
+static void *_ascending_search(rt_varea_t varea, rt_size_t req_size,
+ rt_ubase_t align_mask, struct _mm_range limit)
+{
+ void *ret = ARCH_MAP_FAILED;
+ while (varea && varea->start < limit.end)
+ {
+ void *candidate = varea->start + varea->size;
+ candidate = _align(candidate, align_mask);
+
+ if (candidate > limit.end || limit.end - candidate + 1 < req_size)
+ break;
+
+ rt_varea_t nx_va = ASPACE_VAREA_NEXT(varea);
+ if (nx_va)
+ {
+ rt_size_t gap_size =
+ _lower(limit.end, nx_va->start - 1) - candidate + 1;
+ if (gap_size >= req_size)
+ {
+ ret = candidate;
+ break;
+ }
+ }
+ else
+ {
+ ret = candidate;
+ }
+ varea = nx_va;
+ }
+ return ret;
+}
+
+/** find suitable place in [limit_start, limit_end] */
+static void *_find_head_and_asc_search(rt_aspace_t aspace, rt_size_t req_size,
+ rt_ubase_t align_mask,
+ struct _mm_range limit)
+{
+ void *va = ARCH_MAP_FAILED;
+
+ rt_varea_t varea = _aspace_bst_search_exceed(aspace, limit.start);
+ if (varea)
+ {
+ void *candidate = _align(limit.start, align_mask);
+ rt_size_t gap_size = varea->start - candidate;
+ if (gap_size >= req_size)
+ {
+ rt_varea_t former = _aspace_bst_search(aspace, limit.start);
+ if (former)
+ {
+ candidate = _align(former->start + former->size, align_mask);
+ gap_size = varea->start - candidate;
+
+ if (gap_size >= req_size)
+ va = candidate;
+ else
+ va = _ascending_search(varea, req_size, align_mask, limit);
+ }
+ else
+ {
+ va = candidate;
+ }
+ }
+ else
+ {
+ va = _ascending_search(varea, req_size, align_mask, limit);
+ }
+ }
+ else
+ {
+ void *candidate;
+ rt_size_t gap_size;
+ rt_varea_t former = _aspace_bst_search(aspace, limit.start);
+
+ candidate = former ? former->start + former->size : limit.start;
+ candidate = _align(candidate, align_mask);
+ gap_size = limit.end - candidate + 1;
+
+ if (gap_size >= req_size)
+ va = candidate;
+ }
+
+ return va;
+}
+
+static void *_find_free(rt_aspace_t aspace, void *prefer, rt_size_t req_size,
+ void *limit_start, rt_size_t limit_size,
+ mm_flag_t flags)
+{
+ rt_varea_t varea = NULL;
+ void *va = ARCH_MAP_FAILED;
+ struct _mm_range limit = {limit_start, limit_start + limit_size - 1};
+
+ rt_ubase_t align_mask = ~0ul;
+ if (flags & MMF_REQUEST_ALIGN)
+ {
+ align_mask = ~((1 << MMF_GET_ALIGN(flags)) - 1);
+ }
+
+ if (prefer != ARCH_MAP_FAILED)
+ {
+ prefer = _align(prefer, align_mask);
+ struct _mm_range range = {prefer, prefer + req_size - 1};
+ varea = _aspace_bst_search_overlap(aspace, range);
+
+ if (!varea)
+ {
+ va = prefer;
+ }
+ else if (flags & MMF_MAP_FIXED)
+ {
+ }
+ else
+ {
+ va = _ascending_search(varea, req_size, align_mask, limit);
+ if (va == ARCH_MAP_FAILED)
+ {
+ limit.end = varea->start - 1;
+ va = _find_head_and_asc_search(aspace, req_size, align_mask,
+ limit);
+ }
+ }
+ }
+ else
+ {
+ va = _find_head_and_asc_search(aspace, req_size, align_mask, limit);
+ }
+
+ return va;
+}
+
+int rt_aspace_load_page(rt_aspace_t aspace, void *addr, rt_size_t npage)
+{
+ int err = RT_EOK;
+ rt_varea_t varea = _aspace_bst_search(aspace, addr);
+ void *end = addr + (npage << ARCH_PAGE_SHIFT);
+
+ if (!varea)
+ {
+ LOG_W("%s: varea not exist", __func__);
+ err = -RT_ENOENT;
+ }
+ else if (addr >= end || (rt_size_t)addr & ARCH_PAGE_MASK ||
+ _not_in_range(addr, npage << ARCH_PAGE_SHIFT, varea->start,
+ varea->size))
+ {
+ LOG_W("%s: Unaligned parameter or out of range", __func__);
+ err = -RT_EINVAL;
+ }
+ else
+ {
+ err = _do_prefetch(aspace, varea, addr, npage << ARCH_PAGE_SHIFT);
+ }
+ return err;
+}
+
+int rt_aspace_offload_page(rt_aspace_t aspace, void *addr, rt_size_t npage)
+{
+ return -RT_ENOSYS;
+}
+
+int mm_aspace_control(rt_aspace_t aspace, void *addr, enum rt_mmu_cntl cmd)
+{
+ int err;
+ rt_varea_t varea = _aspace_bst_search(aspace, addr);
+ if (varea)
+ {
+ err = rt_hw_mmu_control(aspace, varea->start, varea->size, cmd);
+ }
+ else
+ {
+ err = -RT_ENOENT;
+ }
+
+ return err;
+}
+
+int rt_aspace_traversal(rt_aspace_t aspace,
+ int (*fn)(rt_varea_t varea, void *arg), void *arg)
+{
+ rt_varea_t varea = ASPACE_VAREA_FIRST(aspace);
+ while (varea)
+ {
+ fn(varea, arg);
+ varea = ASPACE_VAREA_NEXT(varea);
+ }
+
+ return 0;
+}
+
+static int _dump(rt_varea_t varea, void *arg)
+{
+ rt_kprintf("%s[%p - %p]\n", varea->mem_obj->get_name(varea), varea->start,
+ varea->start + varea->size);
+ return 0;
+}
+
+void rt_aspace_print_all(rt_aspace_t aspace)
+{
+ rt_aspace_traversal(aspace, _dump, NULL);
+}
diff --git a/components/mm/mm_aspace.h b/components/mm/mm_aspace.h
new file mode 100644
index 0000000000..900b3635be
--- /dev/null
+++ b/components/mm/mm_aspace.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-11-14 WangXiaoyao the first version
+ */
+#ifndef __MM_ASPACE_H__
+#define __MM_ASPACE_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <stddef.h>
+
+#include "avl_adpt.h"
+#include "mm_fault.h"
+#include "mm_flag.h"
+
+#define MM_PAGE_SHIFT 12
+#define MM_PA_TO_OFF(pa) ((uintptr_t)(pa) >> MM_PAGE_SHIFT)
+
+#ifndef RT_USING_SMP
+typedef rt_spinlock_t mm_spinlock;
+
+#define MM_PGTBL_LOCK_INIT(aspace)
+#define MM_PGTBL_LOCK(aspace) (rt_hw_spin_lock(&((aspace)->pgtbl_lock)))
+#define MM_PGTBL_UNLOCK(aspace) (rt_hw_spin_unlock(&((aspace)->pgtbl_lock)))
+
+#else
+typedef rt_hw_spinlock_t mm_spinlock;
+
+#define MM_PGTBL_LOCK_INIT(aspace) (rt_hw_spin_lock_init(&((aspace)->pgtbl_lock)))
+#define MM_PGTBL_LOCK(aspace) (rt_hw_spin_lock(&((aspace)->pgtbl_lock)))
+#define MM_PGTBL_UNLOCK(aspace) (rt_hw_spin_unlock(&((aspace)->pgtbl_lock)))
+
+#endif /* RT_USING_SMP */
+
+struct rt_aspace;
+struct rt_varea;
+struct rt_mem_obj;
+
+extern struct rt_aspace rt_kernel_space;
+
+typedef struct rt_aspace
+{
+ void *start;
+ rt_size_t size;
+
+ void *page_table;
+ mm_spinlock pgtbl_lock;
+
+ struct _aspace_tree tree;
+ struct rt_mutex bst_lock;
+} *rt_aspace_t;
+
+typedef struct rt_varea
+{
+ void *start;
+ rt_size_t size;
+ rt_size_t offset;
+
+ rt_size_t attr;
+ rt_size_t flag;
+
+ struct rt_aspace *aspace;
+ struct rt_mem_obj *mem_obj;
+
+ struct _aspace_node node;
+
+ struct rt_page *frames;
+ void *data;
+} *rt_varea_t;
+
+typedef struct rt_mm_va_hint
+{
+ void *limit_start;
+ rt_size_t limit_range_size;
+
+ void *prefer;
+ const rt_size_t map_size;
+
+ mm_flag_t flags;
+} *rt_mm_va_hint_t;
+
+typedef struct rt_mem_obj
+{
+ void (*hint_free)(rt_mm_va_hint_t hint);
+ void (*on_page_fault)(struct rt_varea *varea, struct rt_mm_fault_msg *msg);
+
+ /* do pre open bushiness like inc a ref */
+ void (*on_varea_open)(struct rt_varea *varea);
+ /* do post close bushiness like def a ref */
+ void (*on_varea_close)(struct rt_varea *varea);
+
+ void (*on_page_offload)(struct rt_varea *varea, void *vaddr, rt_size_t size);
+
+ const char *(*get_name)(rt_varea_t varea);
+} *rt_mem_obj_t;
+
+extern struct rt_mem_obj rt_mm_dummy_mapper;
+
+enum rt_mmu_cntl
+{
+ MMU_CNTL_NONCACHE,
+ MMU_CNTL_CACHE,
+ MMU_CNTL_DUMMY_END,
+};
+
+/**
+ * @brief Lock to access page table of address space
+ */
+#define WR_LOCK(aspace) \
+ rt_thread_self() ? rt_mutex_take(&(aspace)->bst_lock, RT_WAITING_FOREVER) \
+ : 0
+#define WR_UNLOCK(aspace) \
+ rt_thread_self() ? rt_mutex_release(&(aspace)->bst_lock) : 0
+
+#define RD_LOCK(aspace) WR_LOCK(aspace)
+#define RD_UNLOCK(aspace) WR_UNLOCK(aspace)
+
+rt_aspace_t rt_aspace_create(void *start, rt_size_t length, void *pgtbl);
+
+rt_aspace_t rt_aspace_init(rt_aspace_t aspace, void *start, rt_size_t length,
+ void *pgtbl);
+
+void rt_aspace_delete(rt_aspace_t aspace);
+
+void rt_aspace_detach(rt_aspace_t aspace);
+
+/**
+ * @brief Memory Map on Virtual Address Space to Mappable Object
+ * *INFO There is no restriction to use NULL address(physical/virtual).
+ * Vaddr passing in addr must be page aligned. If vaddr is MM_MAP_FAILED,
+ * a suitable address will be chose automatically.
+ *
+ * @param aspace target virtual address space
+ * @param addr virtual address of the mapping
+ * @param length length of mapping region
+ * @param attr MMU attribution
+ * @param flags desired memory protection and behaviour of the mapping
+ * @param mem_obj memory map backing store object
+ * @param offset offset of mapping in 4KB page for mem_obj
+ * @return int E_OK on success, with addr set to vaddr of mapping
+ * E_INVAL
+ */
+int rt_aspace_map(rt_aspace_t aspace, void **addr, rt_size_t length, rt_size_t attr,
+ mm_flag_t flags, rt_mem_obj_t mem_obj, rt_size_t offset);
+
+/** no malloc routines call */
+int rt_aspace_map_static(rt_aspace_t aspace, rt_varea_t varea, void **addr,
+ rt_size_t length, rt_size_t attr, mm_flag_t flags,
+ rt_mem_obj_t mem_obj, rt_size_t offset);
+
+/**
+ * @brief Memory Map on Virtual Address Space to Physical Memory
+ *
+ * @param aspace target virtual address space
+ * @param hint hint of mapping va
+ * @param attr MMU attribution
+ * @param pa_off (physical address >> 12)
+ * @param ret_va pointer to the location to store va
+ * @return int E_OK on success, with ret_va set to vaddr of mapping
+ * E_INVAL
+ */
+int rt_aspace_map_phy(rt_aspace_t aspace, rt_mm_va_hint_t hint, rt_size_t attr,
+ rt_size_t pa_off, void **ret_va);
+
+/** no malloc routines call */
+int rt_aspace_map_phy_static(rt_aspace_t aspace, rt_varea_t varea,
+ rt_mm_va_hint_t hint, rt_size_t attr, rt_size_t pa_off,
+ void **ret_va);
+
+/**
+ * @brief Remove any mappings overlap the range [addr, addr + bytes)
+ *
+ * @param aspace
+ * @param addr
+ * @param length
+ * @return int
+ */
+int rt_aspace_unmap(rt_aspace_t aspace, void *addr, rt_size_t length);
+
+int mm_aspace_control(rt_aspace_t aspace, void *addr, enum rt_mmu_cntl cmd);
+
+int rt_aspace_load_page(rt_aspace_t aspace, void *addr, rt_size_t npage);
+
+int rt_aspace_offload_page(rt_aspace_t aspace, void *addr, rt_size_t npage);
+
+int rt_aspace_traversal(rt_aspace_t aspace,
+ int (*fn)(rt_varea_t varea, void *arg), void *arg);
+
+void rt_aspace_print_all(rt_aspace_t aspace);
+
+void rt_varea_insert_page(rt_varea_t varea, void *page_addr);
+
+void rt_varea_free_pages(rt_varea_t varea);
+
+void rt_varea_offload_page(rt_varea_t varea, void *vaddr, rt_size_t size);
+
+#endif /* __MM_ASPACE_H__ */
diff --git a/components/mm/mm_fault.c b/components/mm/mm_fault.c
new file mode 100644
index 0000000000..08d7c84196
--- /dev/null
+++ b/components/mm/mm_fault.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-12-06 WangXiaoyao the first version
+ */
+#include <rtthread.h>
+
+#ifdef RT_USING_SMART
+#include <lwp.h>
+#include <lwp_syscall.h>
+#include "mm_aspace.h"
+#include "mm_fault.h"
+#include "mm_flag.h"
+#include "mm_private.h"
+#include <mmu.h>
+#include <tlb.h>
+
+#define DBG_TAG "mm.fault"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#define UNRECOVERABLE 0
+#define RECOVERABLE 1
+
+static int _fetch_page(rt_varea_t varea, struct rt_mm_fault_msg *msg)
+{
+ int err = UNRECOVERABLE;
+ varea->mem_obj->on_page_fault(varea, msg);
+ if (msg->response.status == MM_FAULT_STATUS_OK)
+ {
+ void *store = msg->response.vaddr;
+ rt_size_t store_sz = msg->response.size;
+
+ if (msg->vaddr + store_sz > varea->start + varea->size)
+ {
+ LOG_W("%s more size of buffer is provided than varea", __func__);
+ }
+ else
+ {
+ rt_hw_mmu_map(varea->aspace, msg->vaddr, store + PV_OFFSET,
+ store_sz, varea->attr);
+ rt_hw_tlb_invalidate_range(varea->aspace, msg->vaddr, store_sz,
+ ARCH_PAGE_SIZE);
+ err = RECOVERABLE;
+ }
+ }
+ return err;
+}
+
+static int _read_fault(rt_varea_t varea, void *pa, struct rt_mm_fault_msg *msg)
+{
+ int err = UNRECOVERABLE;
+ if (msg->fault_type == MM_FAULT_TYPE_PAGE_FAULT)
+ {
+ RT_ASSERT(pa == ARCH_MAP_FAILED);
+ err = _fetch_page(varea, msg);
+ }
+ else
+ {
+ /* signal a fault to user? */
+ }
+ return err;
+}
+
+static int _write_fault(rt_varea_t varea, void *pa, struct rt_mm_fault_msg *msg)
+{
+ int err = UNRECOVERABLE;
+ if (msg->fault_type == MM_FAULT_TYPE_PAGE_FAULT)
+ {
+ RT_ASSERT(pa == ARCH_MAP_FAILED);
+ err = _fetch_page(varea, msg);
+ }
+ else if (msg->fault_type == MM_FAULT_TYPE_ACCESS_FAULT &&
+ varea->flag & MMF_COW)
+ {
+ }
+ else
+ {
+ /* signal a fault to user? */
+ }
+ return err;
+}
+
+static int _exec_fault(rt_varea_t varea, void *pa, struct rt_mm_fault_msg *msg)
+{
+ int err = UNRECOVERABLE;
+ if (msg->fault_type == MM_FAULT_TYPE_PAGE_FAULT)
+ {
+ RT_ASSERT(pa == ARCH_MAP_FAILED);
+ err = _fetch_page(varea, msg);
+ }
+ return err;
+}
+
+int rt_mm_fault_try_fix(struct rt_mm_fault_msg *msg)
+{
+ struct rt_lwp *lwp = lwp_self();
+ int err = UNRECOVERABLE;
+ uintptr_t va = (uintptr_t)msg->vaddr;
+ va &= ~ARCH_PAGE_MASK;
+ msg->vaddr = (void *)va;
+
+ if (lwp)
+ {
+ rt_aspace_t aspace = lwp->aspace;
+ rt_varea_t varea = _aspace_bst_search(aspace, msg->vaddr);
+ if (varea)
+ {
+ void *pa = rt_hw_mmu_v2p(aspace, msg->vaddr);
+ msg->off = (msg->vaddr - varea->start) >> ARCH_PAGE_SHIFT;
+
+ /* permission checked by fault op */
+ switch (msg->fault_op)
+ {
+ case MM_FAULT_OP_READ:
+ err = _read_fault(varea, pa, msg);
+ break;
+ case MM_FAULT_OP_WRITE:
+ err = _write_fault(varea, pa, msg);
+ break;
+ case MM_FAULT_OP_EXECUTE:
+ err = _exec_fault(varea, pa, msg);
+ break;
+ }
+ }
+ }
+
+ return err;
+}
+
+#endif /* RT_USING_SMART */
diff --git a/components/mm/mm_fault.h b/components/mm/mm_fault.h
new file mode 100644
index 0000000000..17657f5200
--- /dev/null
+++ b/components/mm/mm_fault.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-12-06 WangXiaoyao the first version
+ */
+#ifndef __MM_FAULT_H__
+#define __MM_FAULT_H__
+
+#include <rtthread.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#define MM_FAULT_STATUS_OK 0
+#define MM_FAULT_STATUS_UNRECOVERABLE 1
+
+struct rt_mm_fault_res
+{
+ void *vaddr;
+ rt_size_t size;
+ int status;
+};
+
+enum rt_mm_fault_op
+{
+ MM_FAULT_OP_READ = 1,
+ MM_FAULT_OP_WRITE,
+ MM_FAULT_OP_EXECUTE,
+};
+
+enum rt_mm_fault_type
+{
+ MM_FAULT_TYPE_ACCESS_FAULT,
+ MM_FAULT_TYPE_PAGE_FAULT,
+ MM_FAULT_TYPE_BUS_ERROR,
+ MM_FAULT_TYPE_GENERIC,
+};
+
+struct rt_mm_fault_msg
+{
+ enum rt_mm_fault_op fault_op;
+ enum rt_mm_fault_type fault_type;
+ rt_size_t off;
+ void *vaddr;
+
+ struct rt_mm_fault_res response;
+};
+
+/* MMU base page fault handler, return 1 is */
+int rt_mm_fault_try_fix(struct rt_mm_fault_msg *msg);
+
+#endif /* __MM_FAULT_H__ */
diff --git a/components/mm/mm_flag.h b/components/mm/mm_flag.h
new file mode 100644
index 0000000000..4f15415159
--- /dev/null
+++ b/components/mm/mm_flag.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-11-23 WangXiaoyao the first version
+ */
+#ifndef __MM_FLAG_H__
+#define __MM_FLAG_H__
+
+/**
+ * @brief mm_flag_t
+ * |max ------- 7|6 ----- 0|
+ * | control | align |
+ *
+ * there should be no more than 25 flags
+ */
+typedef unsigned long mm_flag_t;
+
+#define _MMF_CNTL_SHIFT 7
+#define _MMF_ALIGN_MASK 0x7f
+#define _MMF_CNTL_MASK (~((1 << _MMF_CNTL_SHIFT) - 1))
+#define _DEF_FLAG(index) (1 << (_MMF_CNTL_SHIFT + (index)))
+
+enum mm_flag_cntl
+{
+ /**
+ * @brief Indicate a possible COW mapping
+ */
+ MMF_MAP_PRIVATE = _DEF_FLAG(0),
+ MMF_COW = _DEF_FLAG(1),
+
+ /**
+ * @brief [POSIX MAP_FIXED] When MAP_FIXED is set in the flags argument, the
+ * implementation is informed that the value of pa shall be addr, exactly.
+ * If a MAP_FIXED request is successful, the mapping established
+ * by mmap() replaces any previous mappings for the pages in the range
+ * [pa,pa+len) of the process.
+ */
+ MMF_MAP_FIXED = _DEF_FLAG(2),
+
+ /**
+ * @brief The backup page frame is allocated and setted only until it is
+ * truly necessary by the user
+ */
+ MMF_PREFETCH = _DEF_FLAG(3),
+
+ MMF_HUGEPAGE = _DEF_FLAG(4),
+
+ MMF_TEXT = _DEF_FLAG(5),
+
+ /**
+ * @brief a non-locked memory can be swapped out when required, this is
+ * reserved for future
+ */
+ MMF_NONLOCKED = _DEF_FLAG(20),
+
+ /**
+ * @brief An alignment is specified in flags that the mapping must admit
+ */
+ MMF_REQUEST_ALIGN = _DEF_FLAG(21),
+};
+
+#define MMF_GET_ALIGN(src) ((src & _MMF_ALIGN_MASK))
+#define MMF_SET_ALIGN(src, align) \
+ ((src & ~_MMF_ALIGN_MASK) | (__builtin_ffsl(align) - 1))
+
+#define MMF_GET_CNTL(src) (src & _MMF_CNTL_MASK)
+#define MMF_TEST_CNTL(src, flag) (src & flag)
+#define MMF_SET_CNTL(src, flag) ((src) | (flag))
+#define MMF_CLEAR_CNTL(src, flag) ((src) & ~(flag))
+
+/**
+ * @brief Create Flags
+ *
+ * example: MMF_CREATE(0, 0)
+ * MMF_CREATE(MM_MAP_FIXED, 0x2000)
+ *
+ * Direct use of flag is also acceptable: (MMF_MAP_FIXED | MMF_PREFETCH)
+ */
+#define MMF_CREATE(cntl, align) \
+ (align ? (MMF_SET_CNTL((mm_flag_t)0, (cntl) | MMF_REQUEST_ALIGN) | \
+ MMF_SET_ALIGN((mm_flag_t)0, align)) \
+ : (MMF_SET_CNTL((mm_flag_t)0, (cntl) & ~MMF_REQUEST_ALIGN)))
+
+#undef _DEF_FLAG
+#endif /* __MM_FLAG_H__ */
diff --git a/components/mm/mm_object.c b/components/mm/mm_object.c
new file mode 100644
index 0000000000..739c8ecdda
--- /dev/null
+++ b/components/mm/mm_object.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-11-30 WangXiaoyao the first version
+ */
+
+#include <rtthread.h>
+
+#include "mm_aspace.h"
+#include "mm_fault.h"
+#include "mm_page.h"
+#include <mmu.h>
+
+#define DBG_TAG "mm.object"
+#define DBG_LVL DBG_INFO
+#include "rtdbg.h"
+
+static const char *get_name(rt_varea_t varea)
+{
+ return "dummy-mapper";
+}
+
+void rt_varea_insert_page(rt_varea_t varea, void *page_addr)
+{
+ rt_page_t page = rt_page_addr2page(page_addr);
+
+ if (varea->frames == NULL)
+ {
+ varea->frames = page;
+ page->next = NULL;
+ }
+ else
+ {
+ varea->frames->pre = page;
+ page->next = varea->frames;
+ varea->frames = page;
+ }
+}
+
+void rt_varea_free_pages(rt_varea_t varea)
+{
+ rt_page_t page = varea->frames;
+
+ while (page)
+ {
+ rt_page_t next = page->next;
+ void *pg_va = rt_page_page2addr(page);
+ rt_pages_free(pg_va, 0);
+ page = next;
+ }
+}
+
+void rt_varea_offload_page(rt_varea_t varea, void *vaddr, rt_size_t size)
+{
+ void *vend = vaddr + size;
+ while (vaddr != vend)
+ {
+ rt_page_t page = rt_page_addr2page(vaddr);
+ page->pre->next = page->next;
+ page->next->pre = page->pre;
+ rt_pages_free(vaddr, 0);
+ vaddr += ARCH_PAGE_SIZE;
+ }
+}
+
+static void on_page_fault(struct rt_varea *varea, struct rt_mm_fault_msg *msg)
+{
+ void *page;
+ page = rt_pages_alloc(0);
+
+ if (!page)
+ {
+ LOG_W("%s: page alloc failed", __func__);
+ return;
+ }
+
+ msg->response.status = MM_FAULT_STATUS_OK;
+ msg->response.size = ARCH_PAGE_SIZE;
+ msg->response.vaddr = page;
+
+ rt_varea_insert_page(varea, page);
+}
+
+static void on_varea_open(struct rt_varea *varea)
+{
+ varea->data = NULL;
+}
+
+static void on_varea_close(struct rt_varea *varea)
+{
+}
+
+static void on_page_offload(rt_varea_t varea, void *vaddr, rt_size_t size)
+{
+ rt_varea_offload_page(varea, vaddr, size);
+}
+
+struct rt_mem_obj rt_mm_dummy_mapper = {
+ .get_name = get_name,
+ .on_page_fault = on_page_fault,
+ .hint_free = NULL,
+ .on_varea_open = on_varea_open,
+ .on_varea_close = on_varea_close,
+ .on_page_offload = on_page_offload,
+};
diff --git a/components/mm/mm_page.c b/components/mm/mm_page.c
new file mode 100644
index 0000000000..7d897789da
--- /dev/null
+++ b/components/mm/mm_page.c
@@ -0,0 +1,644 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-11-01 Jesven The first version
+ * 2022-12-13 WangXiaoyao Hot-pluggable, extensible
+ * page management algorithm
+ */
+#include <rtthread.h>
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "mm_fault.h"
+#include "mm_private.h"
+#include "mm_aspace.h"
+#include "mm_flag.h"
+#include "mm_page.h"
+#include <mmu.h>
+
+#define DBG_TAG "mm.page"
+#define DBG_LVL DBG_WARNING
+#include <rtdbg.h>
+
+#ifdef RT_USING_SMART
+#include "lwp_arch_comm.h"
+
+#define CT_ASSERT(name, x) \
+ struct assert_##name \
+ { \
+ char ary[2 * (x)-1]; \
+ }
+#ifdef ARCH_CPU_64BIT
+CT_ASSERT(order_huge_pg, RT_PAGE_MAX_ORDER > ARCH_PAGE_SHIFT - 2);
+#else
+CT_ASSERT(size_width, sizeof(rt_size_t) == sizeof(rt_size_t));
+#endif /* ARCH_CPU_64BIT */
+
+#else
+#define PV_OFFSET 0
+#endif /* RT_USING_SMART */
+
+static rt_size_t init_mpr_align_start;
+static rt_size_t init_mpr_align_end;
+static void *init_mpr_cont_start;
+
+static struct rt_varea mpr_varea;
+
+static struct rt_page *page_list[RT_PAGE_MAX_ORDER];
+
+#define page_start ((rt_page_t)rt_mpr_start)
+
+static rt_size_t page_nr;
+static rt_size_t early_offset;
+
+static const char *get_name(rt_varea_t varea)
+{
+ return "master-page-record";
+}
+
+static void hint_free(rt_mm_va_hint_t hint)
+{
+ hint->flags = MMF_MAP_FIXED;
+ hint->limit_start = rt_kernel_space.start;
+ hint->limit_range_size = rt_kernel_space.size;
+ hint->prefer = rt_mpr_start;
+}
+
+static void on_page_fault(struct rt_varea *varea, struct rt_mm_fault_msg *msg)
+{
+ void *init_start = (void *)init_mpr_align_start;
+ void *init_end = (void *)init_mpr_align_end;
+ if (msg->vaddr < init_end && msg->vaddr >= init_start)
+ {
+ rt_size_t offset = msg->vaddr - init_start;
+ msg->response.status = MM_FAULT_STATUS_OK;
+ msg->response.vaddr = init_mpr_cont_start + offset;
+ msg->response.size = ARCH_PAGE_SIZE;
+ }
+ else
+ {
+ void *raw_page = rt_pages_alloc(0);
+ msg->response.status = MM_FAULT_STATUS_OK;
+ msg->response.vaddr = raw_page;
+ msg->response.size = ARCH_PAGE_SIZE;
+ }
+}
+
+static struct rt_mem_obj mm_page_mapper = {
+ .get_name = get_name,
+ .on_page_fault = on_page_fault,
+ .hint_free = hint_free,
+};
+
+static inline void *page_to_addr(rt_page_t page)
+{
+ return (void *)((page - page_start) << ARCH_PAGE_SHIFT) - PV_OFFSET;
+}
+
+static inline rt_page_t addr_to_page(rt_page_t pg_start, void *addr)
+{
+ addr += PV_OFFSET;
+ return &pg_start[((uintptr_t)addr >> ARCH_PAGE_SHIFT)];
+}
+
+#define FLOOR(val, align) (((rt_size_t)(val) + (align)-1) & ~((align)-1))
+
+const rt_size_t shadow_mask =
+ ((1ul << (RT_PAGE_MAX_ORDER + ARCH_PAGE_SHIFT - 1)) - 1);
+
+const rt_size_t rt_mpr_size = FLOOR(
+ ((1ul << (ARCH_VADDR_WIDTH - ARCH_PAGE_SHIFT))) * sizeof(struct rt_page),
+ ARCH_PAGE_SIZE);
+
+void *rt_mpr_start;
+
+rt_weak int rt_hw_clz(unsigned long n)
+{
+ return __builtin_clzl(n);
+}
+
+rt_weak int rt_hw_ctz(unsigned long n)
+{
+ return __builtin_ctzl(n);
+}
+
+rt_size_t rt_page_bits(rt_size_t size)
+{
+ int bit = sizeof(rt_size_t) * 8 - rt_hw_clz(size) - 1;
+
+ if ((size ^ (1UL << bit)) != 0)
+ {
+ bit++;
+ }
+ bit -= ARCH_PAGE_SHIFT;
+ if (bit < 0)
+ {
+ bit = 0;
+ }
+ return bit;
+}
+
+struct rt_page *rt_page_addr2page(void *addr)
+{
+ return addr_to_page(page_start, addr);
+}
+
+void *rt_page_page2addr(struct rt_page *p)
+{
+ return page_to_addr(p);
+}
+
+static inline struct rt_page *buddy_get(struct rt_page *p,
+ rt_uint32_t size_bits)
+{
+ rt_size_t addr;
+
+ addr = (rt_size_t)rt_page_page2addr(p);
+ addr ^= (1UL << (size_bits + ARCH_PAGE_SHIFT));
+ return rt_page_addr2page((void *)addr);
+}
+
+static void page_remove(struct rt_page *p, rt_uint32_t size_bits)
+{
+ if (p->pre)
+ {
+ p->pre->next = p->next;
+ }
+ else
+ {
+ page_list[size_bits] = p->next;
+ }
+
+ if (p->next)
+ {
+ p->next->pre = p->pre;
+ }
+
+ p->size_bits = ARCH_ADDRESS_WIDTH_BITS;
+}
+
+static void page_insert(struct rt_page *p, rt_uint32_t size_bits)
+{
+ p->next = page_list[size_bits];
+ if (p->next)
+ {
+ p->next->pre = p;
+ }
+ p->pre = 0;
+ page_list[size_bits] = p;
+ p->size_bits = size_bits;
+}
+
+static void _pages_ref_inc(struct rt_page *p, rt_uint32_t size_bits)
+{
+ struct rt_page *page_head;
+ int idx;
+
+ /* find page group head */
+ idx = p - page_start;
+ idx = idx & ~((1UL << size_bits) - 1);
+
+ page_head = page_start + idx;
+ page_head = (void *)page_head + early_offset;
+ page_head->ref_cnt++;
+}
+
+static int _pages_ref_get(struct rt_page *p, rt_uint32_t size_bits)
+{
+ struct rt_page *page_head;
+ int idx;
+
+ /* find page group head */
+ idx = p - page_start;
+ idx = idx & ~((1UL << size_bits) - 1);
+
+ page_head = page_start + idx;
+ return page_head->ref_cnt;
+}
+
+static int _pages_free(struct rt_page *p, rt_uint32_t size_bits)
+{
+ rt_uint32_t level = size_bits;
+ struct rt_page *buddy;
+
+ RT_ASSERT(p >= page_start);
+ RT_ASSERT((void *)p < rt_mpr_start + rt_mpr_size);
+ RT_ASSERT(rt_kmem_v2p(p));
+ RT_ASSERT(p->ref_cnt > 0);
+ RT_ASSERT(p->size_bits == ARCH_ADDRESS_WIDTH_BITS);
+ RT_ASSERT(size_bits < RT_PAGE_MAX_ORDER);
+
+ p->ref_cnt--;
+ if (p->ref_cnt != 0)
+ {
+ return 0;
+ }
+
+ while (level < RT_PAGE_MAX_ORDER - 1)
+ {
+ buddy = buddy_get(p, level);
+ if (buddy && buddy->size_bits == level)
+ {
+ page_remove(buddy, level);
+ p = (p < buddy) ? p : buddy;
+ level++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ page_insert(p, level);
+ return 1;
+}
+
+static struct rt_page *_pages_alloc(rt_uint32_t size_bits)
+{
+ struct rt_page *p;
+
+ if (page_list[size_bits])
+ {
+ p = page_list[size_bits];
+ page_remove(p, size_bits);
+ }
+ else
+ {
+ rt_uint32_t level;
+
+ for (level = size_bits + 1; level < RT_PAGE_MAX_ORDER; level++)
+ {
+ if (page_list[level])
+ {
+ break;
+ }
+ }
+ if (level == RT_PAGE_MAX_ORDER)
+ {
+ return 0;
+ }
+
+ p = page_list[level];
+ page_remove(p, level);
+ while (level > size_bits)
+ {
+ page_insert(p, level - 1);
+ p = buddy_get(p, level - 1);
+ level--;
+ }
+ }
+ p->size_bits = ARCH_ADDRESS_WIDTH_BITS;
+ p->ref_cnt = 1;
+ return p;
+}
+
+static void _early_page_remove(rt_page_t page, rt_uint32_t size_bits)
+{
+ rt_page_t page_cont = (void *)page + early_offset;
+ if (page_cont->pre)
+ {
+ rt_page_t pre_cont = (void *)page_cont->pre + early_offset;
+ pre_cont->next = page_cont->next;
+ }
+ else
+ {
+ page_list[size_bits] = page_cont->next;
+ }
+
+ if (page_cont->next)
+ {
+ rt_page_t next_cont = (void *)page_cont->next + early_offset;
+ next_cont->pre = page_cont->pre;
+ }
+
+ page_cont->size_bits = ARCH_ADDRESS_WIDTH_BITS;
+}
+
+static void _early_page_insert(rt_page_t page, int size_bits)
+{
+ RT_ASSERT((void *)page >= rt_mpr_start &&
+ (void *)page - rt_mpr_start < +rt_mpr_size);
+ rt_page_t page_cont = (void *)page + early_offset;
+
+ page_cont->next = page_list[size_bits];
+ if (page_cont->next)
+ {
+ rt_page_t next_cont = (void *)page_cont->next + early_offset;
+ next_cont->pre = page;
+ }
+ page_cont->pre = 0;
+ page_list[size_bits] = page;
+ page_cont->size_bits = size_bits;
+}
+
+static struct rt_page *_early_pages_alloc(rt_uint32_t size_bits)
+{
+ struct rt_page *p;
+
+ if (page_list[size_bits])
+ {
+ p = page_list[size_bits];
+ _early_page_remove(p, size_bits);
+ }
+ else
+ {
+ rt_uint32_t level;
+
+ for (level = size_bits + 1; level < RT_PAGE_MAX_ORDER; level++)
+ {
+ if (page_list[level])
+ {
+ break;
+ }
+ }
+ if (level == RT_PAGE_MAX_ORDER)
+ {
+ return 0;
+ }
+
+ p = page_list[level];
+ _early_page_remove(p, level);
+ while (level > size_bits)
+ {
+ _early_page_insert(p, level - 1);
+ p = buddy_get(p, level - 1);
+ level--;
+ }
+ }
+ rt_page_t page_cont = (void *)p + early_offset;
+ page_cont->size_bits = ARCH_ADDRESS_WIDTH_BITS;
+ page_cont->ref_cnt = 1;
+ return p;
+}
+
+int rt_page_ref_get(void *addr, rt_uint32_t size_bits)
+{
+ struct rt_page *p;
+ rt_base_t level;
+ int ref;
+
+ p = rt_page_addr2page(addr);
+ level = rt_hw_interrupt_disable();
+ ref = _pages_ref_get(p, size_bits);
+ rt_hw_interrupt_enable(level);
+ return ref;
+}
+
+void rt_page_ref_inc(void *addr, rt_uint32_t size_bits)
+{
+ struct rt_page *p;
+ rt_base_t level;
+
+ p = rt_page_addr2page(addr);
+ level = rt_hw_interrupt_disable();
+ _pages_ref_inc(p, size_bits);
+ rt_hw_interrupt_enable(level);
+}
+
+static rt_page_t (*pages_alloc_handler)(rt_uint32_t size_bits);
+
+void *rt_pages_alloc(rt_uint32_t size_bits)
+{
+ struct rt_page *p;
+ rt_base_t level;
+
+ level = rt_hw_interrupt_disable();
+ p = pages_alloc_handler(size_bits);
+ rt_hw_interrupt_enable(level);
+ return page_to_addr(p);
+}
+
+int rt_pages_free(void *addr, rt_uint32_t size_bits)
+{
+ struct rt_page *p;
+ int real_free = 0;
+
+ p = rt_page_addr2page(addr);
+ if (p)
+ {
+ rt_base_t level;
+ level = rt_hw_interrupt_disable();
+ real_free = _pages_free(p, size_bits);
+ rt_hw_interrupt_enable(level);
+ }
+ return real_free;
+}
+
+void rt_page_list(void) __attribute__((alias("list_page")));
+
+void list_page(void)
+{
+ int i;
+ rt_size_t total = 0;
+
+ rt_base_t level;
+ level = rt_hw_interrupt_disable();
+
+ for (i = 0; i < RT_PAGE_MAX_ORDER; i++)
+ {
+ struct rt_page *p = page_list[i];
+
+ rt_kprintf("level %d ", i);
+
+ while (p)
+ {
+ total += (1UL << i);
+ rt_kprintf("[0x%08p]", rt_page_page2addr(p));
+ p = p->next;
+ }
+ rt_kprintf("\n");
+ }
+ rt_hw_interrupt_enable(level);
+ rt_kprintf("free pages is 0x%08x\n", total);
+ rt_kprintf("-------------------------------\n");
+}
+MSH_CMD_EXPORT(list_page, show page info);
+
+void rt_page_get_info(rt_size_t *total_nr, rt_size_t *free_nr)
+{
+ int i;
+ rt_size_t total_free = 0;
+ rt_base_t level;
+
+ level = rt_hw_interrupt_disable();
+ for (i = 0; i < RT_PAGE_MAX_ORDER; i++)
+ {
+ struct rt_page *p = page_list[i];
+
+ while (p)
+ {
+ total_free += (1UL << i);
+ p = p->next;
+ }
+ }
+ rt_hw_interrupt_enable(level);
+ *total_nr = page_nr;
+ *free_nr = total_free;
+}
+
+void rt_page_init(rt_region_t reg)
+{
+ int i;
+ rt_region_t shadow;
+
+ /* inclusive start, exclusive end */
+ reg.start += ARCH_PAGE_MASK;
+ reg.start &= ~ARCH_PAGE_MASK;
+ reg.end &= ~ARCH_PAGE_MASK;
+ page_nr = ((reg.end - reg.start) >> ARCH_PAGE_SHIFT);
+ shadow.start = reg.start & ~shadow_mask;
+ shadow.end = FLOOR(reg.end, shadow_mask + 1);
+ LOG_D("[Init page] start: 0x%lx, end: 0x%lx, total: 0x%lx", reg.start,
+ reg.end, page_nr);
+
+ int err;
+
+ /* init free list */
+ for (i = 0; i < RT_PAGE_MAX_ORDER; i++)
+ {
+ page_list[i] = 0;
+ }
+
+ /* map MPR area */
+ err = rt_aspace_map_static(&rt_kernel_space, &mpr_varea, &rt_mpr_start,
+ rt_mpr_size, MMU_MAP_K_RWCB, MMF_MAP_FIXED,
+ &mm_page_mapper, 0);
+
+ if (err != RT_EOK)
+ {
+ LOG_E("MPR map failed with size %lx at %p", rt_mpr_size, rt_mpr_start);
+ while (1)
+ ;
+ }
+
+ /* calculate footprint */
+ init_mpr_align_start =
+ (rt_size_t)addr_to_page(page_start, (void *)shadow.start) &
+ ~ARCH_PAGE_MASK;
+ init_mpr_align_end =
+ FLOOR(addr_to_page(page_start, (void *)shadow.end), ARCH_PAGE_SIZE);
+ rt_size_t init_mpr_size = init_mpr_align_end - init_mpr_align_start;
+ rt_size_t init_mpr_npage = init_mpr_size >> ARCH_PAGE_SHIFT;
+
+ init_mpr_cont_start = (void *)reg.start;
+ void *init_mpr_cont_end = init_mpr_cont_start + init_mpr_size;
+ early_offset = init_mpr_cont_start - (void *)init_mpr_align_start;
+ rt_page_t mpr_cont = rt_mpr_start + early_offset;
+
+ /* mark init mpr pages as illegal */
+ rt_page_t head_cont = addr_to_page(mpr_cont, (void *)reg.start);
+ rt_page_t tail_cont = addr_to_page(mpr_cont, (void *)reg.end);
+ for (rt_page_t iter = head_cont; iter < tail_cont; iter++)
+ {
+ iter->size_bits = ARCH_ADDRESS_WIDTH_BITS;
+ }
+
+ /* mark shadow pages as illegal */
+ rt_page_t shad_head_cont = addr_to_page(mpr_cont, (void *)shadow.start);
+ for (rt_page_t iter = shad_head_cont; iter < head_cont; iter++)
+ {
+ iter->size_bits = ARCH_ADDRESS_WIDTH_BITS;
+ }
+ rt_page_t shad_tail_cont = addr_to_page(mpr_cont, (void *)shadow.end);
+ for (rt_page_t iter = tail_cont; iter < shad_tail_cont; iter++)
+ {
+ iter->size_bits = ARCH_ADDRESS_WIDTH_BITS;
+ }
+
+ /* insert reserved pages to list */
+ reg.start = (rt_size_t)init_mpr_cont_end;
+ const int max_order = RT_PAGE_MAX_ORDER + ARCH_PAGE_SHIFT - 1;
+ while (reg.start != reg.end)
+ {
+ struct rt_page *p;
+ int align_bits;
+ int size_bits;
+
+ size_bits =
+ ARCH_ADDRESS_WIDTH_BITS - 1 - rt_hw_clz(reg.end - reg.start);
+ align_bits = rt_hw_ctz(reg.start);
+ if (align_bits < size_bits)
+ {
+ size_bits = align_bits;
+ }
+ if (size_bits > max_order)
+ {
+ size_bits = max_order;
+ }
+
+ p = addr_to_page(mpr_cont, (void *)reg.start);
+ p->size_bits = ARCH_ADDRESS_WIDTH_BITS;
+ p->ref_cnt = 0;
+
+ /* insert to list */
+ _early_page_insert((void *)p - early_offset,
+ size_bits - ARCH_PAGE_SHIFT);
+ reg.start += (1UL << size_bits);
+ }
+
+ pages_alloc_handler = _early_pages_alloc;
+ /* doing the page table bushiness */
+ rt_aspace_load_page(&rt_kernel_space, (void *)init_mpr_align_start,
+ init_mpr_npage);
+ if (rt_hw_mmu_tbl_get() == rt_kernel_space.page_table)
+ rt_page_cleanup();
+}
+
+static void _load_mpr_area(void *head, void *tail)
+{
+ void *iter = (void *)((uintptr_t)head & ~ARCH_PAGE_MASK);
+ tail = (void *)FLOOR(tail, ARCH_PAGE_SIZE);
+
+ while (iter != tail)
+ {
+ void *paddr = rt_kmem_v2p(iter);
+ if (paddr == ARCH_MAP_FAILED)
+ {
+ rt_aspace_load_page(&rt_kernel_space, iter, 1);
+ }
+ iter += ARCH_PAGE_SIZE;
+ }
+}
+
+int rt_page_install(rt_region_t region)
+{
+ int err = -RT_EINVAL;
+ if (region.end != region.start && !(region.start & ARCH_PAGE_MASK) &&
+ !(region.end & ARCH_PAGE_MASK) &&
+ !((region.end - region.start) & shadow_mask))
+ {
+ void *head = addr_to_page(page_start, (void *)region.start);
+ void *tail = addr_to_page(page_start, (void *)region.end);
+
+ page_nr += ((region.end - region.start) >> ARCH_PAGE_SHIFT);
+
+ _load_mpr_area(head, tail);
+
+ while (region.start != region.end)
+ {
+ struct rt_page *p;
+ int size_bits;
+
+ size_bits = RT_PAGE_MAX_ORDER - 1;
+ p = addr_to_page(page_start, (void *)region.start);
+ p->size_bits = ARCH_ADDRESS_WIDTH_BITS;
+ p->ref_cnt = 1;
+
+ _pages_free(p, size_bits);
+ region.start += (1UL << (size_bits + ARCH_PAGE_SHIFT));
+ }
+ err = 0;
+ }
+ return err;
+}
+
+void rt_page_cleanup(void)
+{
+ early_offset = 0;
+ pages_alloc_handler = _pages_alloc;
+}
diff --git a/components/mm/mm_page.h b/components/mm/mm_page.h
new file mode 100644
index 0000000000..788a5ef5b0
--- /dev/null
+++ b/components/mm/mm_page.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-11-01 Jesven The first version
+ * 2022-12-13 WangXiaoyao Hot-pluggable, extensible
+ * page management algorithm
+ */
+#ifndef __MM_PAGE_H__
+#define __MM_PAGE_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <stdint.h>
+
+#define GET_FLOOR(type) \
+ (1ul << (8 * sizeof(rt_size_t) - __builtin_clzl(2 * sizeof(type) - 1) - 1))
+#define DEF_PAGE_T(fields) \
+ typedef struct rt_page {\
+ union {struct {fields}; char _padding[GET_FLOOR(struct {fields})];};\
+ } *rt_page_t
+
+DEF_PAGE_T(
+ struct rt_page *next; /* same level next */
+ struct rt_page *pre; /* same level pre */
+
+ rt_uint32_t size_bits; /* if is ARCH_ADDRESS_WIDTH_BITS, means not free */
+ rt_uint32_t ref_cnt; /* page group ref count */
+);
+
+#undef GET_FLOOR
+#undef DEF_PAGE_T
+
+typedef struct tag_region
+{
+ rt_size_t start;
+ rt_size_t end;
+} rt_region_t;
+
+extern const rt_size_t rt_mpr_size;
+extern void *rt_mpr_start;
+
+void rt_page_init(rt_region_t reg);
+
+void rt_page_cleanup(void);
+
+void *rt_pages_alloc(rt_uint32_t size_bits);
+
+void rt_page_ref_inc(void *addr, rt_uint32_t size_bits);
+
+int rt_page_ref_get(void *addr, rt_uint32_t size_bits);
+
+int rt_pages_free(void *addr, rt_uint32_t size_bits);
+
+void rt_page_list(void);
+
+rt_size_t rt_page_bits(rt_size_t size);
+
+void rt_page_get_info(rt_size_t *total_nr, rt_size_t *free_nr);
+
+void *rt_page_page2addr(struct rt_page *p);
+
+struct rt_page *rt_page_addr2page(void *addr);
+
+/**
+ * @brief Install page frames at run-time
+ * Region size must be aligned to 2^(RT_PAGE_MAX_ORDER + ARCH_PAGE_SHIFT - 1)
+ * bytes currently (typically 2 MB).
+ *
+ * !WARNING this API will NOT check whether region is valid or not in list
+ *
+ * @param region region.start as first page frame(inclusive),
+ * region.end as first page frame after free region
+ * @return int 0 on success
+ */
+int rt_page_install(rt_region_t region);
+
+#endif /* __MM_PAGE_H__ */
diff --git a/components/mm/mm_private.h b/components/mm/mm_private.h
new file mode 100644
index 0000000000..0f31fc1fba
--- /dev/null
+++ b/components/mm/mm_private.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-11-14 WangXiaoyao the first version
+ */
+#ifndef __MM_INTERN_H__
+#define __MM_INTERN_H__
+
+#include "mm_aspace.h"
+#include <rtdef.h>
+#include <stddef.h>
+
+/**
+ * @brief DATA STRUCTURE & API USED INTERNALLY
+ *
+ * This is mainly a wrapper layer to actual data structure.
+ * In this way, we can switch to any BST we like by adding new
+ * wrapper code.
+ * Every BST must satisfy the API to support MM
+ *
+ * *INFO: varea range convention
+ * For API, a range is specified by a base and its length.
+ * This provides a clear interface without ambiguity.
+ * For implementation, a range is specified by [start, end] tuple
+ * where both start and end are inclusive.
+ */
+
+struct _mm_range
+{
+ void *start;
+ void *end;
+};
+
+/**
+ * @brief
+ *
+ * @param aspace
+ * @return rt_err_t
+ */
+rt_err_t _aspace_bst_init(struct rt_aspace *aspace);
+
+/**
+ * @brief
+ *
+ * @param aspace
+ * @param start
+ * @return struct rt_varea*
+ */
+struct rt_varea *_aspace_bst_search(struct rt_aspace *aspace, void *start);
+
+/**
+ * @brief Retrieve lowest varea satisfies
+ * ((varea->start >= start) || (varea->end >= start))
+ *
+ * @param aspace
+ * @param length
+ * @param struct _mm_range
+ * @return struct rt_varea*
+ */
+struct rt_varea *_aspace_bst_search_exceed(struct rt_aspace *aspace,
+ void *start);
+
+/**
+ * @brief Retrieve any varea overlaps a specified address range
+ *
+ * @param aspace
+ * @param start
+ * @param length
+ * @return struct rt_varea*
+ */
+struct rt_varea *_aspace_bst_search_overlap(struct rt_aspace *aspace,
+ struct _mm_range range);
+
+/**
+ * @brief Insert a varea into the bst
+ *
+ * @param aspace
+ * @param varea
+ */
+void _aspace_bst_insert(struct rt_aspace *aspace, struct rt_varea *varea);
+
+/**
+ * @brief Remove a varea from the bst
+ *
+ * @param aspace
+ * @param varea
+ */
+void _aspace_bst_remove(struct rt_aspace *aspace, struct rt_varea *varea);
+
+#endif /* __MM_INTERN_H__ */
diff --git a/components/utilities/libadt/SConscript b/components/utilities/libadt/SConscript
new file mode 100644
index 0000000000..a0380669f7
--- /dev/null
+++ b/components/utilities/libadt/SConscript
@@ -0,0 +1,8 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c')
+CPPPATH = [cwd]
+group = DefineGroup('ADT', src, depend = [], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/components/utilities/libadt/avl.c b/components/utilities/libadt/avl.c
new file mode 100644
index 0000000000..9f4d84af2c
--- /dev/null
+++ b/components/utilities/libadt/avl.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-10-12 Jesven first version
+ * 2022-11-14 WangXiaoyao Optimize footprint and performance
+ * Export as ADT for generic use case
+ */
+#include <stddef.h>
+#include <stdint.h>
+
+#include "avl.h"
+
+#define HEIGHT_OF(node) ((node) ? (node)->height : 0)
+#define IS_RCHILD(node) (!((node) - ((node)->parent->avl_right)))
+#define IS_LCHILD(node) (!((node) - ((node)->parent->avl_left)))
+#define NODE_PLACE(node) \
+ IS_LCHILD(node) ? &(node)->parent->avl_left : &(node)->parent->avl_right
+
+static inline void rotate_right(struct util_avl_struct *axis,
+ struct util_avl_struct *lchild,
+ struct util_avl_struct *lrchild,
+ struct util_avl_struct **nodeplace,
+ size_t lrheight)
+{
+ axis->avl_left = lrchild;
+ lchild->avl_right = axis;
+
+ axis->height = lrheight + 1;
+ lchild->height = axis->height + 1;
+
+ lchild->parent = axis->parent;
+ axis->parent = lchild;
+
+ *nodeplace = lchild;
+ if (lrchild != NULL)
+ lrchild->parent = axis;
+}
+
+static inline void midmount_right(struct util_avl_struct *axis,
+ struct util_avl_struct *lchild,
+ struct util_avl_struct *lrchild,
+ struct util_avl_struct **nodeplace,
+ size_t lrheight)
+{
+ lchild->avl_right = lrchild->avl_left;
+ axis->avl_left = lrchild->avl_right;
+ lrchild->avl_left = lchild;
+ lrchild->avl_right = axis;
+
+ lchild->height = lrheight;
+ axis->height = lrheight;
+
+ lchild->parent = lrchild;
+ axis->parent = lrchild;
+ if (lchild->avl_right != NULL)
+ lchild->avl_right->parent = lchild;
+ if (axis->avl_left != NULL)
+ axis->avl_left->parent = axis;
+ *nodeplace = lrchild;
+}
+
+static inline void rotate_left(struct util_avl_struct *axis,
+ struct util_avl_struct *rchild,
+ struct util_avl_struct *rlchild,
+ struct util_avl_struct **nodeplace,
+ size_t rlheight)
+{
+ axis->avl_right = rlchild;
+ rchild->avl_right = axis;
+
+ axis->height = rlheight + 1;
+ rchild->height = axis->height + 1;
+
+ rchild->parent = axis->parent;
+ axis->parent = rchild;
+
+ *nodeplace = rchild;
+ if (rlchild != NULL)
+ rlchild->parent = axis;
+}
+
+static inline void midmount_left(struct util_avl_struct *axis,
+ struct util_avl_struct *rchild,
+ struct util_avl_struct *rlchild,
+ struct util_avl_struct **nodeplace,
+ size_t rlheight)
+{
+ rchild->avl_left = rlchild->avl_right;
+ axis->avl_right = rlchild->avl_left;
+ rlchild->avl_right = rchild;
+ rlchild->avl_left = axis;
+
+ rchild->height = rlheight;
+ axis->height = rlheight;
+
+ rchild->parent = rlchild;
+ axis->parent = rlchild;
+ if (rchild->avl_left != NULL)
+ rchild->avl_left->parent = rchild;
+ if (axis->avl_right != NULL)
+ axis->avl_right->parent = axis;
+
+ *nodeplace = rlchild;
+}
+
+/**
+ * @brief avl insertion & delete conceptually contain 2 stage
+ * 1. insertion/delete of reference
+ * 2. rebalance
+ */
+
+void util_avl_rebalance(struct util_avl_struct *node,
+ struct util_avl_root *root)
+{
+ if (!node)
+ return;
+
+ struct util_avl_struct *axis = node;
+ struct util_avl_struct **nodeplace;
+ do
+ {
+ struct util_avl_struct *lchild = axis->avl_left;
+ struct util_avl_struct *rchild = axis->avl_right;
+ nodeplace = node->parent ? NODE_PLACE(axis) : &root->root_node;
+ int lheight = HEIGHT_OF(lchild);
+ int rheight = HEIGHT_OF(rchild);
+ if (rheight + 1 < lheight)
+ {
+ struct util_avl_struct *lrchild = lchild->avl_right;
+ size_t lrheight = HEIGHT_OF(lrchild);
+ if (HEIGHT_OF(lchild->avl_left) >= lrheight)
+ {
+ rotate_right(axis, lchild, lrchild, nodeplace, lrheight);
+ }
+ else
+ {
+ midmount_right(axis, lchild, lrchild, nodeplace, lrheight);
+ }
+ }
+ else if (lheight + 1 < rheight)
+ {
+ struct util_avl_struct *rlchild = rchild->avl_left;
+ size_t rlheight = HEIGHT_OF(rlchild);
+ if (HEIGHT_OF(rchild->avl_right) >= rlheight)
+ {
+ rotate_left(axis, rchild, rlchild, nodeplace, rlheight);
+ }
+ else
+ {
+ midmount_left(axis, rchild, rlchild, nodeplace, rlheight);
+ }
+ }
+ else
+ {
+ int height = lheight < rheight ? rheight : lheight;
+ if (height == axis->height)
+ break;
+ axis->height = height;
+ }
+ } while (nodeplace != &root->root_node);
+}
+
+void util_avl_remove(struct util_avl_struct *node, struct util_avl_root *root)
+{
+ struct util_avl_struct **nodeplace;
+
+ if (root->root_node == NULL)
+ return;
+
+ if (node->parent != NULL)
+ {
+ nodeplace = NODE_PLACE(node);
+ }
+ else
+ {
+ nodeplace = &root->root_node;
+ }
+
+ /* deletion */
+ if (node->avl_right == NULL)
+ {
+ *nodeplace = node->avl_left;
+ if (node->avl_left != NULL)
+ node->avl_left->parent = node->parent;
+ node = node->parent;
+ }
+ else
+ {
+ struct util_avl_struct *rchild = node->avl_right;
+ if (rchild->avl_left == NULL)
+ {
+ *nodeplace = rchild;
+ rchild->avl_left = node->avl_left;
+ if (rchild->avl_left != NULL)
+ rchild->avl_left->parent = node->parent;
+ rchild->parent = node->parent;
+ node = rchild;
+ }
+ else
+ {
+ struct util_avl_struct *successor = rchild->avl_left;
+ struct util_avl_struct *sparent = rchild;
+ while (successor->avl_left != NULL)
+ {
+ sparent = successor;
+ successor = successor->avl_left;
+ }
+ *nodeplace = successor;
+ sparent->avl_left = successor->avl_right;
+ successor->avl_left = node->avl_left;
+ successor->avl_right = node->avl_right;
+
+ if (successor->avl_left != NULL)
+ successor->avl_left->parent = successor;
+ successor->avl_right->parent = successor;
+
+ if (sparent->avl_left != NULL)
+ sparent->avl_left->parent = sparent;
+ successor->parent = node->parent;
+ node = sparent;
+ }
+ }
+
+ /* rebalance */
+ util_avl_rebalance(node, root);
+ return;
+}
diff --git a/components/utilities/libadt/avl.h b/components/utilities/libadt/avl.h
new file mode 100644
index 0000000000..e0d4811dfd
--- /dev/null
+++ b/components/utilities/libadt/avl.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-10-12 Jesven first version
+ * 2022-11-14 WangXiaoyao Optimize for generic use case
+ * and performance
+ */
+#ifndef __UTIL_TREE_AVL_H__
+#define __UTIL_TREE_AVL_H__
+
+#include <rtdef.h>
+#include <stdint.h>
+
+struct util_avl_struct
+{
+ struct util_avl_struct *avl_left;
+ struct util_avl_struct *avl_right;
+ struct util_avl_struct *parent;
+ size_t height;
+};
+
+#define AVL_ROOT ((struct util_avl_struct *)0)
+
+struct util_avl_root
+{
+ struct util_avl_struct *root_node;
+};
+
+void util_avl_rebalance(struct util_avl_struct *node,
+ struct util_avl_root *root);
+
+void util_avl_remove(struct util_avl_struct *node, struct util_avl_root *root);
+
+static inline void util_avl_link(struct util_avl_struct *new_node,
+ struct util_avl_struct *parent,
+ struct util_avl_struct **nodeplace)
+{
+ new_node->avl_left = AVL_ROOT;
+ new_node->avl_right = AVL_ROOT;
+ new_node->parent = parent;
+ new_node->height = 1;
+ *nodeplace = new_node;
+}
+
+static inline struct util_avl_struct *util_avl_next(
+ struct util_avl_struct *node)
+{
+ struct util_avl_struct *successor = 0;
+ if (node)
+ {
+ if (node->avl_right)
+ {
+ node = node->avl_right;
+ while (node->avl_left)
+ node = node->avl_left;
+ successor = node;
+ }
+ else
+ {
+ while ((successor = node->parent) && (node == successor->avl_right))
+ node = successor;
+ }
+ }
+ return successor;
+}
+
+static inline struct util_avl_struct *util_avl_prev(
+ struct util_avl_struct *node)
+{
+ struct util_avl_struct *predecessor = 0;
+ if (node)
+ {
+ if (node->avl_left)
+ {
+ node = node->avl_left;
+ while (node->avl_right)
+ node = node->avl_right;
+ predecessor = node;
+ }
+ else
+ {
+ while ((predecessor = node->parent) &&
+ (node == predecessor->avl_left))
+ node = predecessor;
+ }
+ }
+ return predecessor;
+}
+
+static inline struct util_avl_struct *util_avl_first(struct util_avl_root *root)
+{
+ struct util_avl_struct *first = root->root_node;
+ if (first)
+ {
+ while (first->avl_left)
+ first = first->avl_left;
+ }
+ return first;
+}
+
+static inline struct util_avl_struct *util_avl_last(struct util_avl_root *root)
+{
+ struct util_avl_struct *last = root->root_node;
+ if (last)
+ {
+ while (last->avl_right)
+ last = last->avl_right;
+ }
+ return last;
+}
+
+#endif /* __UTIL_TREE_AVL_H__ */
diff --git a/include/rtdef.h b/include/rtdef.h
index 593bd856b3..82c41f73c1 100644
--- a/include/rtdef.h
+++ b/include/rtdef.h
@@ -356,7 +356,9 @@ typedef int (*init_fn_t)(void);
#define RT_EIO 8 /**< IO error */
#define RT_EINTR 9 /**< Interrupted system call */
#define RT_EINVAL 10 /**< Invalid argument */
-#define RT_ETRAP 11 /**< trap event */
+#define RT_ETRAP 11 /**< Trap event */
+#define RT_ENOENT 12 /**< No entry */
+#define RT_ENOSPC 13 /**< No space left */
/**@}*/
diff --git a/include/rthw.h b/include/rthw.h
index 3c1e743279..c56223f1cb 100644
--- a/include/rthw.h
+++ b/include/rthw.h
@@ -54,6 +54,11 @@ enum RT_HW_CACHE_OPS
* CPU interfaces
*/
#ifdef RT_USING_CACHE
+
+#ifdef ARCH_RISCV64
+#include <cache.h>
+#endif
+
void rt_hw_cpu_icache_enable(void);
void rt_hw_cpu_icache_disable(void);
rt_base_t rt_hw_cpu_icache_status(void);
diff --git a/libcpu/aarch64/common/context_gcc.S b/libcpu/aarch64/common/context_gcc.S
index 344d7317c6..0a611cbf48 100644
--- a/libcpu/aarch64/common/context_gcc.S
+++ b/libcpu/aarch64/common/context_gcc.S
@@ -183,7 +183,7 @@ rt_hw_get_gtimer_frq:
#ifdef RT_USING_LWP
BL rt_thread_self
MOV X19, X0
- BL lwp_mmu_switch
+ BL lwp_aspace_switch
MOV X0, X19
BL lwp_user_setting_restore
#endif
@@ -514,28 +514,3 @@ vector_serror:
STP X0, X1, [SP, #-0x10]!
BL rt_hw_trap_serror
b .
-
-.global rt_hw_mmu_switch
-rt_hw_mmu_switch:
- MSR TTBR0_EL1, X0
- MRS X1, TCR_EL1
- CMP X0, XZR
- ORR X1, X1, #(1 << 7)
- BEQ 1f
- BIC X1, X1, #(1 << 7)
-1:
- MSR TCR_EL1, X1
- DSB SY
- ISB
- TLBI VMALLE1
- DSB SY
- ISB
- IC IALLUIS
- DSB SY
- ISB
- RET
-
-.global rt_hw_mmu_tbl_get
-rt_hw_mmu_tbl_get:
- MRS X0, TTBR0_EL1
- RET
diff --git a/libcpu/aarch64/common/cpu_ops_common.h b/libcpu/aarch64/common/cpu_ops_common.h
index 3ac0a363c3..5e47584c7b 100644
--- a/libcpu/aarch64/common/cpu_ops_common.h
+++ b/libcpu/aarch64/common/cpu_ops_common.h
@@ -8,7 +8,7 @@
static inline rt_uint64_t get_secondary_entry_pa(void)
{
- rt_uint64_t secondary_entry_pa = (rt_uint64_t)rt_hw_mmu_v2p(&mmu_info, _secondary_cpu_entry);
+ rt_uint64_t secondary_entry_pa = (rt_uint64_t)rt_kmem_v2p(_secondary_cpu_entry);
if (!secondary_entry_pa)
{
diff --git a/libcpu/aarch64/common/cpuport.h b/libcpu/aarch64/common/cpuport.h
index 9f209069ac..cf767b9cfb 100644
--- a/libcpu/aarch64/common/cpuport.h
+++ b/libcpu/aarch64/common/cpuport.h
@@ -11,6 +11,7 @@
#define CPUPORT_H__
#include <armv8.h>
+#include <rtdef.h>
#ifdef RT_USING_SMP
typedef union {
@@ -29,12 +30,22 @@ rt_inline void rt_hw_isb(void)
rt_inline void rt_hw_dmb(void)
{
- asm volatile ("dmb sy":::"memory");
+ asm volatile ("dmb ish":::"memory");
+}
+
+rt_inline void rt_hw_wmb(void)
+{
+ asm volatile ("dmb ishst":::"memory");
+}
+
+rt_inline void rt_hw_rmb(void)
+{
+ asm volatile ("dmb ishld":::"memory");
}
rt_inline void rt_hw_dsb(void)
{
- asm volatile ("dsb sy":::"memory");
+ asm volatile ("dsb ish":::"memory");
}
#endif /*CPUPORT_H__*/
diff --git a/libcpu/aarch64/common/interrupt.c b/libcpu/aarch64/common/interrupt.c
index 3e527640b2..5a0b67160c 100644
--- a/libcpu/aarch64/common/interrupt.c
+++ b/libcpu/aarch64/common/interrupt.c
@@ -15,6 +15,12 @@
#include "gic.h"
#include "gicv3.h"
+#ifdef RT_USING_SMART
+#include "ioremap.h"
+#else
+#define rt_ioremap(x, ...) (x)
+#endif
+
/* exception and interrupt handler table */
struct rt_irq_desc isr_table[MAX_HANDLERS];
@@ -103,11 +109,11 @@ void rt_hw_interrupt_init(void)
/* initialize ARM GIC */
#ifdef RT_USING_SMART
- gic_dist_base = (rt_uint64_t)rt_hw_mmu_map(&mmu_info, 0, (void*)platform_get_gic_dist_base(), 0x2000, MMU_MAP_K_DEVICE);
- gic_cpu_base = (rt_uint64_t)rt_hw_mmu_map(&mmu_info, 0, (void*)platform_get_gic_cpu_base(), 0x1000, MMU_MAP_K_DEVICE);
+ gic_dist_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_dist_base(), 0x2000);
+ gic_cpu_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_cpu_base(), 0x1000);
#ifdef BSP_USING_GICV3
- gic_rdist_base = (rt_uint64_t)rt_hw_mmu_map(&mmu_info, 0, (void*)platform_get_gic_redist_base(),
- RT_CPUS_NR * (2 << 16), MMU_MAP_K_DEVICE);
+ gic_rdist_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_redist_base(),
+ RT_CPUS_NR * (2 << 16));
#endif
#else
gic_dist_base = platform_get_gic_dist_base();
diff --git a/libcpu/aarch64/common/mmu.c b/libcpu/aarch64/common/mmu.c
index 0197e23f0f..d567d111d9 100644
--- a/libcpu/aarch64/common/mmu.c
+++ b/libcpu/aarch64/common/mmu.c
@@ -8,245 +8,44 @@
* 2012-01-10 bernard porting to AM1808
*/
-#include <rtthread.h>
-#include <rthw.h>
#include <board.h>
+#include <rthw.h>
+#include <rtthread.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include "mm_aspace.h"
+#include "mm_page.h"
#include "mmu.h"
+#include "tlb.h"
#ifdef RT_USING_SMART
+#include "ioremap.h"
#include <lwp_mm.h>
-#include <page.h>
#endif
-#define MMU_LEVEL_MASK 0x1ffUL
-#define MMU_LEVEL_SHIFT 9
-#define MMU_ADDRESS_BITS 39
-#define MMU_ADDRESS_MASK 0x0000fffffffff000UL
-#define MMU_ATTRIB_MASK 0xfff0000000000ffcUL
+#define DBG_TAG "hw.mmu"
+#define DBG_LVL DBG_LOG
+#include <rtdbg.h>
+
+#define MMU_LEVEL_MASK 0x1ffUL
+#define MMU_LEVEL_SHIFT 9
+#define MMU_ADDRESS_BITS 39
+#define MMU_ADDRESS_MASK 0x0000fffffffff000UL
+#define MMU_ATTRIB_MASK 0xfff0000000000ffcUL
-#define MMU_TYPE_MASK 3UL
-#define MMU_TYPE_USED 1UL
-#define MMU_TYPE_BLOCK 1UL
-#define MMU_TYPE_TABLE 3UL
-#define MMU_TYPE_PAGE 3UL
+#define MMU_TYPE_MASK 3UL
+#define MMU_TYPE_USED 1UL
+#define MMU_TYPE_BLOCK 1UL
+#define MMU_TYPE_TABLE 3UL
+#define MMU_TYPE_PAGE 3UL
#define MMU_TBL_BLOCK_2M_LEVEL 2
#define MMU_TBL_PAGE_4k_LEVEL 3
#define MMU_TBL_LEVEL_NR 4
-void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr);
-
-struct page_table
-{
- unsigned long page[512];
-};
-
-#ifndef RT_USING_SMART
-#define MMU_TBL_PAGE_NR_MAX 32
-
-static rt_mutex_t mm_lock = RT_NULL;
-
-void rt_mm_lock(void)
-{
- if (rt_thread_self())
- {
- if (!mm_lock)
- {
- mm_lock = rt_mutex_create("mm_lock", RT_IPC_FLAG_FIFO);
- }
- if (mm_lock)
- {
- rt_mutex_take(mm_lock, RT_WAITING_FOREVER);
- }
- }
-}
-
-void rt_mm_unlock(void)
-{
- if (rt_thread_self())
- {
- if (mm_lock)
- {
- rt_mutex_release(mm_lock);
- }
- }
-}
-
-static volatile struct page_table MMUPage[MMU_TBL_PAGE_NR_MAX] __attribute__((aligned(4096)));
-
-#define rt_page_ref_inc(...)
-
-unsigned long rt_pages_alloc(rt_size_t size_bits)
-{
- static unsigned long i = 0;
-
- if (i >= MMU_TBL_PAGE_NR_MAX)
- {
- return RT_NULL;
- }
-
- ++i;
-
- return (unsigned long)&MMUPage[i - 1].page;
-}
-#endif
-
-static struct page_table *__init_page_array;
-static unsigned long __page_off = 0UL;
-unsigned long get_free_page(void)
-{
- if (!__init_page_array)
- {
- unsigned long temp_page_start;
- asm volatile("mov %0, sp":"=r"(temp_page_start));
- __init_page_array = (struct page_table *)(temp_page_start & ~(ARCH_SECTION_MASK));
- __page_off = 2; /* 0, 1 for ttbr0, ttrb1 */
- }
- __page_off++;
- return (unsigned long)(__init_page_array[__page_off - 1].page);
-}
-
-void mmu_memset(char *dst, char v, size_t len)
-{
- while (len--)
- {
- *dst++ = v;
- }
-}
-
-static int _map_single_page_2M(unsigned long *lv0_tbl, unsigned long va, unsigned long pa, unsigned long attr)
-{
- int level;
- unsigned long *cur_lv_tbl = lv0_tbl;
- unsigned long page;
- unsigned long off;
- int level_shift = MMU_ADDRESS_BITS;
-
- if (va & ARCH_SECTION_MASK)
- {
- return MMU_MAP_ERROR_VANOTALIGN;
- }
- if (pa & ARCH_SECTION_MASK)
- {
- return MMU_MAP_ERROR_PANOTALIGN;
- }
- for (level = 0; level < MMU_TBL_BLOCK_2M_LEVEL; level++)
- {
- off = (va >> level_shift);
- off &= MMU_LEVEL_MASK;
- if (!(cur_lv_tbl[off] & MMU_TYPE_USED))
- {
- page = get_free_page();
- if (!page)
- {
- return MMU_MAP_ERROR_NOPAGE;
- }
- mmu_memset((char *)page, 0, ARCH_PAGE_SIZE);
- cur_lv_tbl[off] = page | MMU_TYPE_TABLE;
- }
- page = cur_lv_tbl[off];
- if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK)
- {
- /* is block! error! */
- return MMU_MAP_ERROR_CONFLICT;
- }
- cur_lv_tbl = (unsigned long *)(page & MMU_ADDRESS_MASK);
- level_shift -= MMU_LEVEL_SHIFT;
- }
- attr &= MMU_ATTRIB_MASK;
- pa |= (attr | MMU_TYPE_BLOCK); /* block */
- off = (va >> ARCH_SECTION_SHIFT);
- off &= MMU_LEVEL_MASK;
- cur_lv_tbl[off] = pa;
- return 0;
-}
-
-int armv8_init_map_2M(unsigned long *lv0_tbl, unsigned long va, unsigned long pa, unsigned long count, unsigned long attr)
-{
- unsigned long i;
- int ret;
-
- if (va & ARCH_SECTION_MASK)
- {
- return -1;
- }
- if (pa & ARCH_SECTION_MASK)
- {
- return -1;
- }
- for (i = 0; i < count; i++)
- {
- ret = _map_single_page_2M(lv0_tbl, va, pa, attr);
- va += ARCH_SECTION_SIZE;
- pa += ARCH_SECTION_SIZE;
- if (ret != 0)
- {
- return ret;
- }
- }
- return 0;
-}
-
-static int _kenrel_map_2M(unsigned long *lv0_tbl, unsigned long va, unsigned long pa, unsigned long attr)
-{
- int level;
- unsigned long *cur_lv_tbl = lv0_tbl;
- unsigned long page;
- unsigned long off;
- int level_shift = MMU_ADDRESS_BITS;
-
- if (va & ARCH_SECTION_MASK)
- {
- return MMU_MAP_ERROR_VANOTALIGN;
- }
- if (pa & ARCH_SECTION_MASK)
- {
- return MMU_MAP_ERROR_PANOTALIGN;
- }
- for (level = 0; level < MMU_TBL_BLOCK_2M_LEVEL; level++)
- {
- off = (va >> level_shift);
- off &= MMU_LEVEL_MASK;
- if (!(cur_lv_tbl[off] & MMU_TYPE_USED))
- {
- page = (unsigned long)rt_pages_alloc(0);
- if (!page)
- {
- return MMU_MAP_ERROR_NOPAGE;
- }
- rt_memset((char *)page, 0, ARCH_PAGE_SIZE);
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)page, ARCH_PAGE_SIZE);
- cur_lv_tbl[off] = (page + PV_OFFSET) | MMU_TYPE_TABLE;
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *));
- }
- else
- {
- page = cur_lv_tbl[off];
- page &= MMU_ADDRESS_MASK;
- /* page to va */
- page -= PV_OFFSET;
- rt_page_ref_inc((void *)page, 0);
- }
- page = cur_lv_tbl[off];
- if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK)
- {
- /* is block! error! */
- return MMU_MAP_ERROR_CONFLICT;
- }
- cur_lv_tbl = (unsigned long *)(page & MMU_ADDRESS_MASK);
- cur_lv_tbl = (unsigned long *)((unsigned long)cur_lv_tbl - PV_OFFSET);
- level_shift -= MMU_LEVEL_SHIFT;
- }
- attr &= MMU_ATTRIB_MASK;
- pa |= (attr | MMU_TYPE_BLOCK); /* block */
- off = (va >> ARCH_SECTION_SHIFT);
- off &= MMU_LEVEL_MASK;
- cur_lv_tbl[off] = pa;
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *));
-
- return 0;
-}
+volatile unsigned long MMUTable[512] __attribute__((aligned(4 * 1024)));
struct mmu_level_info
{
@@ -254,7 +53,6 @@ struct mmu_level_info
void *page;
};
-#ifdef RT_USING_LWP
static void _kenrel_unmap_4K(unsigned long *lv0_tbl, void *v_addr)
{
int level;
@@ -313,17 +111,20 @@ static void _kenrel_unmap_4K(unsigned long *lv0_tbl, void *v_addr)
}
level--;
}
- asm volatile("tlbi vae1, %0\ndsb sy"::"r"(v_addr):"memory");
+
return;
}
-static int _kenrel_map_4K(unsigned long *lv0_tbl, unsigned long va, unsigned long pa, unsigned long attr)
+static int _kenrel_map_4K(unsigned long *lv0_tbl, void *vaddr, void *paddr,
+ unsigned long attr)
{
int ret = 0;
int level;
unsigned long *cur_lv_tbl = lv0_tbl;
unsigned long page;
unsigned long off;
+ intptr_t va = (intptr_t)vaddr;
+ intptr_t pa = (intptr_t)paddr;
int level_shift = MMU_ADDRESS_BITS;
if (va & ARCH_PAGE_MASK)
@@ -347,9 +148,11 @@ static int _kenrel_map_4K(unsigned long *lv0_tbl, unsigned long va, unsigned lon
goto err;
}
rt_memset((void *)page, 0, ARCH_PAGE_SIZE);
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)page, ARCH_PAGE_SIZE);
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)page,
+ ARCH_PAGE_SIZE);
cur_lv_tbl[off] = (page + PV_OFFSET) | MMU_TYPE_TABLE;
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *));
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off,
+ sizeof(void *));
}
else
{
@@ -382,139 +185,156 @@ err:
_kenrel_unmap_4K(lv0_tbl, (void *)va);
return ret;
}
-#endif
-static int _kernel_map_fixed(unsigned long *lv0_tbl, unsigned long va, unsigned long pa, unsigned long count, unsigned long attr)
+void *rt_hw_mmu_map(rt_aspace_t aspace, void *v_addr, void *p_addr, size_t size,
+ size_t attr)
{
- unsigned long i;
- int ret;
- unsigned long _attr = MMU_MAP_CUSTOM(MMU_AP_KAUN, attr);
+ int ret = -1;
- if (va & ARCH_SECTION_MASK)
- {
- return -1;
- }
- if (pa & ARCH_SECTION_MASK)
- {
- return -1;
- }
- for (i = 0; i < count; i++)
+ void *unmap_va = v_addr;
+ size_t npages = size >> ARCH_PAGE_SHIFT;
+
+ // TODO trying with HUGEPAGE here
+ while (npages--)
{
- ret = _kenrel_map_2M(lv0_tbl, va, pa, _attr);
- va += ARCH_SECTION_SIZE;
- pa += ARCH_SECTION_SIZE;
+ ret = _kenrel_map_4K(aspace->page_table, v_addr, p_addr, attr);
if (ret != 0)
{
- return ret;
+ /* error, undo map */
+ while (unmap_va != v_addr)
+ {
+ _kenrel_unmap_4K(aspace->page_table, (void *)unmap_va);
+ unmap_va += ARCH_PAGE_SIZE;
+ }
+ break;
}
+ v_addr += ARCH_PAGE_SIZE;
+ p_addr += ARCH_PAGE_SIZE;
}
- return 0;
-}
-/************ setting el1 mmu register**************
- MAIR_EL1
- index 0 : memory outer writeback, write/read alloc
- index 1 : memory nocache
- index 2 : device nGnRnE
- *****************************************************/
-void mmu_tcr_init(void)
-{
- unsigned long val64;
-
- val64 = 0x00447fUL;
- __asm__ volatile("msr MAIR_EL1, %0\n dsb sy\n"::"r"(val64));
-
- /* TCR_EL1 */
- val64 = (16UL << 0) /* t0sz 48bit */
- | (0x0UL << 6) /* reserved */
- | (0x0UL << 7) /* epd0 */
- | (0x3UL << 8) /* t0 wb cacheable */
- | (0x3UL << 10) /* inner shareable */
- | (0x2UL << 12) /* t0 outer shareable */
- | (0x0UL << 14) /* t0 4K */
- | (16UL << 16) /* t1sz 48bit */
- | (0x0UL << 22) /* define asid use ttbr0.asid */
- | (0x0UL << 23) /* epd1 */
- | (0x3UL << 24) /* t1 inner wb cacheable */
- | (0x3UL << 26) /* t1 outer wb cacheable */
- | (0x2UL << 28) /* t1 outer shareable */
- | (0x2UL << 30) /* t1 4k */
- | (0x1UL << 32) /* 001b 64GB PA */
- | (0x0UL << 35) /* reserved */
- | (0x1UL << 36) /* as: 0:8bit 1:16bit */
- | (0x0UL << 37) /* tbi0 */
- | (0x0UL << 38); /* tbi1 */
- __asm__ volatile("msr TCR_EL1, %0\n"::"r"(val64));
-}
-
-/* dump 2nd level page table */
-void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
-{
-}
+ if (ret == 0)
+ {
+ return unmap_va;
+ }
-void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb)
-{
+ return NULL;
}
-volatile unsigned long MMUTable[512] __attribute__((aligned(4 * 1024)));
-void rt_hw_mmu_setmtt(unsigned long vaddrStart,
- unsigned long vaddrEnd,
- unsigned long paddrStart,
- unsigned long attr)
+void rt_hw_mmu_unmap(rt_aspace_t aspace, void *v_addr, size_t size)
{
- unsigned long count;
+ // caller guarantee that v_addr & size are page aligned
+ size_t npages = size >> ARCH_PAGE_SHIFT;
- if (vaddrStart & ARCH_SECTION_MASK)
+ if (!aspace->page_table)
{
- while (1);
- }
- if (paddrStart & ARCH_SECTION_MASK)
- {
- while (1);
- }
- if (vaddrStart > vaddrEnd)
- {
- while (1);
+ return;
}
- count = vaddrEnd + 1;
- if (count & ARCH_SECTION_MASK)
+
+ while (npages--)
{
- while (1);
+ _kenrel_unmap_4K(aspace->page_table, v_addr);
+ v_addr += ARCH_PAGE_SIZE;
}
- count -= vaddrStart;
- if (count == 0)
+}
+
+void rt_hw_aspace_switch(rt_aspace_t aspace)
+{
+ if (aspace != &rt_kernel_space)
{
- while (1);
+ void *pgtbl = aspace->page_table;
+ pgtbl = _rt_kmem_v2p(pgtbl);
+ uintptr_t tcr;
+
+ __asm__ volatile("msr ttbr0_el1, %0" ::"r"(pgtbl) : "memory");
+
+ __asm__ volatile("mrs %0, tcr_el1" : "=r"(tcr));
+ tcr &= ~(1ul << 7);
+ __asm__ volatile("msr tcr_el1, %0\n"
+ "isb" ::"r"(tcr)
+ : "memory");
+
+ rt_hw_tlb_invalidate_all_local();
}
- count >>= ARCH_SECTION_SHIFT;
- _kernel_map_fixed((unsigned long *)MMUTable, vaddrStart, paddrStart, count, attr);
}
void rt_hw_mmu_ktbl_set(unsigned long tbl)
{
#ifdef RT_USING_SMART
tbl += PV_OFFSET;
- __asm__ volatile("msr TTBR1_EL1, %0\n dsb sy\nisb"::"r"(tbl):"memory");
+ __asm__ volatile("msr TTBR1_EL1, %0\n dsb sy\nisb" ::"r"(tbl) : "memory");
#else
- __asm__ volatile("msr TTBR0_EL1, %0\n dsb sy\nisb"::"r"(tbl):"memory");
+ __asm__ volatile("msr TTBR0_EL1, %0\n dsb sy\nisb" ::"r"(tbl) : "memory");
#endif
- __asm__ volatile("tlbi vmalle1\n dsb sy\nisb":::"memory");
- __asm__ volatile("ic ialluis\n dsb sy\nisb":::"memory");
+ __asm__ volatile("tlbi vmalle1\n dsb sy\nisb" ::: "memory");
+ __asm__ volatile("ic ialluis\n dsb sy\nisb" ::: "memory");
}
-void rt_hw_mmu_setup(struct mem_desc *mdesc, int desc_nr)
+/**
+ * @brief setup Page Table for kernel space. It's a fixed map
+ * and all mappings cannot be changed after initialization.
+ *
+ * Memory region in struct mem_desc must be page aligned,
+ * otherwise is a failure and no report will be
+ * returned.
+ *
+ * @param mmu_info
+ * @param mdesc
+ * @param desc_nr
+ */
+void rt_hw_mmu_setup(rt_aspace_t aspace, struct mem_desc *mdesc, int desc_nr)
{
- /* set page table */
- for (; desc_nr > 0; desc_nr--)
+ void *err;
+ for (size_t i = 0; i < desc_nr; i++)
{
- rt_hw_mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end,
- mdesc->paddr_start, mdesc->attr);
+ size_t attr;
+ switch (mdesc->attr)
+ {
+ case NORMAL_MEM:
+ attr = MMU_MAP_K_RWCB;
+ break;
+ case NORMAL_NOCACHE_MEM:
+ attr = MMU_MAP_K_RWCB;
+ break;
+ case DEVICE_MEM:
+ attr = MMU_MAP_K_DEVICE;
+ break;
+ default:
+ attr = MMU_MAP_K_DEVICE;
+ }
+
+ struct rt_mm_va_hint hint = {.flags = MMF_MAP_FIXED,
+ .limit_start = aspace->start,
+ .limit_range_size = aspace->size,
+ .map_size = mdesc->vaddr_end -
+ mdesc->vaddr_start + 1,
+ .prefer = (void *)mdesc->vaddr_start};
+
+ rt_aspace_map_phy_static(aspace, &mdesc->varea, &hint, attr,
+ mdesc->paddr_start >> MM_PAGE_SHIFT, &err);
mdesc++;
}
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)MMUTable, sizeof MMUTable);
- rt_hw_mmu_ktbl_set((unsigned long)MMUTable);
+
+ rt_hw_mmu_ktbl_set((unsigned long)rt_kernel_space.page_table);
+ rt_page_cleanup();
}
+
+#ifdef RT_USING_SMART
+static inline void _init_region(void *vaddr, size_t size)
+{
+ rt_ioremap_start = vaddr;
+ rt_ioremap_size = size;
+ rt_mpr_start = rt_ioremap_start - rt_mpr_size;
+}
+#else
+
+#define RTOS_VEND ((void *)0xfffffffff000UL)
+static inline void _init_region(void *vaddr, size_t size)
+{
+ rt_mpr_start = RTOS_VEND - rt_mpr_size;
+}
+#endif
+
/**
* This function will initialize rt_mmu_info structure.
*
@@ -526,11 +346,12 @@ void rt_hw_mmu_setup(struct mem_desc *mdesc, int desc_nr)
*
* @return 0 on successful and -1 for fail
*/
-int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void *v_address, size_t size, size_t *vtable, size_t pv_off)
+int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, size_t size,
+ size_t *vtable, size_t pv_off)
{
size_t va_s, va_e;
- if (!mmu_info || !vtable)
+ if (!aspace || !vtable)
{
return -1;
}
@@ -551,463 +372,292 @@ int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void *v_address, size_t size, size
return -1;
}
- mmu_info->vtable = vtable;
- mmu_info->vstart = va_s;
- mmu_info->vend = va_e;
- mmu_info->pv_off = pv_off;
+#ifdef RT_USING_SMART
+ rt_aspace_init(aspace, (void *)KERNEL_VADDR_START, 0 - KERNEL_VADDR_START,
+ vtable);
+#else
+ rt_aspace_init(aspace, (void *)0x1000, RTOS_VEND - (void *)0x1000, vtable);
+#endif
+
+ _init_region(v_address, size);
return 0;
}
-int rt_hw_mmu_ioremap_init(rt_mmu_info *mmu_info, void *v_address, size_t size)
+/************ setting el1 mmu register**************
+ MAIR_EL1
+ index 0 : memory outer writeback, write/read alloc
+ index 1 : memory nocache
+ index 2 : device nGnRnE
+ *****************************************************/
+void mmu_tcr_init(void)
{
- return 0;
+ unsigned long val64;
+
+ val64 = 0x00447fUL;
+ __asm__ volatile("msr MAIR_EL1, %0\n dsb sy\n" ::"r"(val64));
+
+ /* TCR_EL1 */
+ val64 = (16UL << 0) /* t0sz 48bit */
+ | (0x0UL << 6) /* reserved */
+ | (0x0UL << 7) /* epd0 */
+ | (0x3UL << 8) /* t0 wb cacheable */
+ | (0x3UL << 10) /* inner shareable */
+ | (0x2UL << 12) /* t0 outer shareable */
+ | (0x0UL << 14) /* t0 4K */
+ | (16UL << 16) /* t1sz 48bit */
+ | (0x0UL << 22) /* define asid use ttbr0.asid */
+ | (0x0UL << 23) /* epd1 */
+ | (0x3UL << 24) /* t1 inner wb cacheable */
+ | (0x3UL << 26) /* t1 outer wb cacheable */
+ | (0x2UL << 28) /* t1 outer shareable */
+ | (0x2UL << 30) /* t1 4k */
+ | (0x1UL << 32) /* 001b 64GB PA */
+ | (0x0UL << 35) /* reserved */
+ | (0x1UL << 36) /* as: 0:8bit 1:16bit */
+ | (0x0UL << 37) /* tbi0 */
+ | (0x0UL << 38); /* tbi1 */
+ __asm__ volatile("msr TCR_EL1, %0\n" ::"r"(val64));
}
-#ifdef RT_USING_SMART
-static size_t find_vaddr(rt_mmu_info *mmu_info, int pages)
+struct page_table
{
- size_t loop_pages;
- size_t va;
- size_t find_va = 0;
- int n = 0;
- size_t i;
+ unsigned long page[512];
+};
- if (!pages)
+static struct page_table *__init_page_array;
+static unsigned long __page_off = 0UL;
+unsigned long get_free_page(void)
+{
+ if (!__init_page_array)
{
- return 0;
+ unsigned long temp_page_start;
+ asm volatile("mov %0, sp" : "=r"(temp_page_start));
+ __init_page_array =
+ (struct page_table *)(temp_page_start & ~(ARCH_SECTION_MASK));
+ __page_off = 2; /* 0, 1 for ttbr0, ttrb1 */
}
+ __page_off++;
+ return (unsigned long)(__init_page_array[__page_off - 1].page);
+}
- if (!mmu_info)
+static int _map_single_page_2M(unsigned long *lv0_tbl, unsigned long va,
+ unsigned long pa, unsigned long attr)
+{
+ int level;
+ unsigned long *cur_lv_tbl = lv0_tbl;
+ unsigned long page;
+ unsigned long off;
+ int level_shift = MMU_ADDRESS_BITS;
+
+ if (va & ARCH_SECTION_MASK)
{
- return 0;
+ return MMU_MAP_ERROR_VANOTALIGN;
}
-
- loop_pages = mmu_info->vend - mmu_info->vstart + 1;
- loop_pages <<= (ARCH_SECTION_SHIFT - ARCH_PAGE_SHIFT);
- va = mmu_info->vstart;
- va <<= ARCH_SECTION_SHIFT;
- for (i = 0; i < loop_pages; i++, va += ARCH_PAGE_SIZE)
+ if (pa & ARCH_SECTION_MASK)
{
- if (_rt_hw_mmu_v2p(mmu_info, (void *)va))
- {
- n = 0;
- find_va = 0;
- continue;
- }
- if (!find_va)
+ return MMU_MAP_ERROR_PANOTALIGN;
+ }
+ for (level = 0; level < MMU_TBL_BLOCK_2M_LEVEL; level++)
+ {
+ off = (va >> level_shift);
+ off &= MMU_LEVEL_MASK;
+ if (!(cur_lv_tbl[off] & MMU_TYPE_USED))
{
- find_va = va;
+ page = get_free_page();
+ if (!page)
+ {
+ return MMU_MAP_ERROR_NOPAGE;
+ }
+ rt_memset((char *)page, 0, ARCH_PAGE_SIZE);
+ cur_lv_tbl[off] = page | MMU_TYPE_TABLE;
}
- n++;
- if (n >= pages)
+ page = cur_lv_tbl[off];
+ if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK)
{
- return find_va;
+ /* is block! error! */
+ return MMU_MAP_ERROR_CONFLICT;
}
+ cur_lv_tbl = (unsigned long *)(page & MMU_ADDRESS_MASK);
+ level_shift -= MMU_LEVEL_SHIFT;
}
+ attr &= MMU_ATTRIB_MASK;
+ pa |= (attr | MMU_TYPE_BLOCK); /* block */
+ off = (va >> ARCH_SECTION_SHIFT);
+ off &= MMU_LEVEL_MASK;
+ cur_lv_tbl[off] = pa;
return 0;
}
-static int check_vaddr(rt_mmu_info *mmu_info, void *va, int pages)
+static int _init_map_2M(unsigned long *lv0_tbl, unsigned long va,
+ unsigned long pa, unsigned long count,
+ unsigned long attr)
{
- size_t loop_va;
-
- if (!pages)
- {
- return -1;
- }
-
- if (!mmu_info)
- {
- return -1;
- }
+ unsigned long i;
+ int ret;
- loop_va = ((size_t)va >> ARCH_SECTION_SHIFT);
- if (loop_va < mmu_info->vstart || loop_va > mmu_info->vend)
+ if (va & ARCH_SECTION_MASK)
{
return -1;
}
- loop_va += ((pages << ARCH_PAGE_SHIFT) >> ARCH_SECTION_SHIFT);
- if (loop_va < mmu_info->vstart || loop_va > mmu_info->vend + 1)
+ if (pa & ARCH_SECTION_MASK)
{
return -1;
}
-
- loop_va = (size_t)va & ~ARCH_PAGE_MASK;
- while (pages--)
+ for (i = 0; i < count; i++)
{
- if (_rt_hw_mmu_v2p(mmu_info, (void *)loop_va))
+ ret = _map_single_page_2M(lv0_tbl, va, pa, attr);
+ va += ARCH_SECTION_SIZE;
+ pa += ARCH_SECTION_SIZE;
+ if (ret != 0)
{
- return -1;
+ return ret;
}
- loop_va += ARCH_PAGE_SIZE;
}
return 0;
}
-static void __rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, size_t npages)
+static unsigned long *_query(rt_aspace_t aspace, void *vaddr, int *plvl_shf)
{
- size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK;
+ int level;
+ unsigned long va = (unsigned long)vaddr;
+ unsigned long *cur_lv_tbl;
+ unsigned long page;
+ unsigned long off;
+ int level_shift = MMU_ADDRESS_BITS;
- if (!mmu_info || !mmu_info->vtable)
- {
- return;
- }
+ cur_lv_tbl = aspace->page_table;
+ RT_ASSERT(cur_lv_tbl);
- while (npages--)
+ for (level = 0; level < MMU_TBL_PAGE_4k_LEVEL; level++)
{
- _kenrel_unmap_4K(mmu_info->vtable, (void *)loop_va);
- loop_va += ARCH_PAGE_SIZE;
- }
-}
+ off = (va >> level_shift);
+ off &= MMU_LEVEL_MASK;
-static int __rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, size_t npages, size_t attr)
-{
- int ret = -1;
- size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK;
- size_t loop_pa = (size_t)p_addr & ~ARCH_PAGE_MASK;
- size_t unmap_va = loop_va;
+ if (!(cur_lv_tbl[off] & MMU_TYPE_USED))
+ {
+ return (void *)0;
+ }
- if (mmu_info)
- {
- while (npages--)
+ page = cur_lv_tbl[off];
+ if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK)
{
- ret = _kenrel_map_4K(mmu_info->vtable, loop_va, loop_pa, attr);
- if (ret != 0)
- {
- /* error, undo map */
- while (unmap_va != loop_va)
- {
- _kenrel_unmap_4K(mmu_info->vtable, (void *)unmap_va);
- unmap_va += ARCH_PAGE_SIZE;
- }
- break;
- }
- loop_va += ARCH_PAGE_SIZE;
- loop_pa += ARCH_PAGE_SIZE;
+ *plvl_shf = level_shift;
+ return &cur_lv_tbl[off];
}
+
+ cur_lv_tbl = (unsigned long *)(page & MMU_ADDRESS_MASK);
+ cur_lv_tbl = (unsigned long *)((unsigned long)cur_lv_tbl - PV_OFFSET);
+ level_shift -= MMU_LEVEL_SHIFT;
}
- return ret;
-}
-#endif
+ /* now is level MMU_TBL_PAGE_4k_LEVEL */
+ off = (va >> ARCH_PAGE_SHIFT);
+ off &= MMU_LEVEL_MASK;
+ page = cur_lv_tbl[off];
-static void rt_hw_cpu_tlb_invalidate(void)
-{
- __asm__ volatile("tlbi vmalle1\n dsb sy\n isb sy\n");
+ if (!(page & MMU_TYPE_USED))
+ {
+ return (void *)0;
+ }
+ *plvl_shf = level_shift;
+ return &cur_lv_tbl[off];
}
-#ifdef RT_USING_SMART
-void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, size_t size, size_t attr)
+void *rt_hw_mmu_v2p(rt_aspace_t aspace, void *v_addr)
{
- size_t pa_s, pa_e;
- size_t vaddr;
- int pages;
- int ret;
+ int level_shift;
+ unsigned long paddr;
+ unsigned long *pte = _query(aspace, v_addr, &level_shift);
- if (!size)
+ if (pte)
{
- return 0;
- }
- pa_s = (size_t)p_addr;
- pa_e = (size_t)p_addr + size - 1;
- pa_s >>= ARCH_PAGE_SHIFT;
- pa_e >>= ARCH_PAGE_SHIFT;
- pages = pa_e - pa_s + 1;
- if (v_addr)
- {
- vaddr = (size_t)v_addr;
- pa_s = (size_t)p_addr;
- if ((vaddr & ARCH_PAGE_MASK) != (pa_s & ARCH_PAGE_MASK))
- {
- return 0;
- }
- vaddr &= ~ARCH_PAGE_MASK;
- if (check_vaddr(mmu_info, (void *)vaddr, pages) != 0)
- {
- return 0;
- }
+ paddr = *pte & MMU_ADDRESS_MASK;
+ paddr |= (uintptr_t)v_addr & ((1ul << level_shift) - 1);
}
else
{
- vaddr = find_vaddr(mmu_info, pages);
+ paddr = (unsigned long)ARCH_MAP_FAILED;
}
- if (vaddr)
- {
- rt_enter_critical();
- ret = __rt_hw_mmu_map(mmu_info, (void *)vaddr, p_addr, pages, attr);
- if (ret == 0)
- {
- rt_hw_cpu_tlb_invalidate();
- rt_exit_critical();
- return (void *)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK));
- }
- rt_exit_critical();
- }
- return 0;
+ return (void *)paddr;
}
-#else
-void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr)
-{
- return p_addr;
-}
-#endif
-#ifdef RT_USING_SMART
-static int __rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t npages, size_t attr)
+static int _noncache(uintptr_t *pte)
{
- size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK;
- size_t loop_pa;
-
- if (!mmu_info)
+ int err = 0;
+ const uintptr_t idx_shift = 2;
+ const uintptr_t idx_mask = 0x7 << idx_shift;
+ uintptr_t entry = *pte;
+ if ((entry & idx_mask) == (NORMAL_MEM << idx_shift))
{
- return -1;
- }
-
- while (npages--)
- {
- loop_pa = (size_t)rt_pages_alloc(0);
- if (!loop_pa)
- {
- goto err;
- }
- loop_pa += mmu_info->pv_off;
- _kenrel_map_4K(mmu_info->vtable, loop_va, loop_pa, attr);
- loop_va += ARCH_PAGE_SIZE;
+ *pte = (entry & ~idx_mask) | (NORMAL_NOCACHE_MEM << idx_shift);
}
- return 0;
-err:
+ else
{
- /* error, unmap and quit */
- int i;
- void *va, *pa;
-
- va = (void *)((size_t)v_addr & ~ARCH_PAGE_MASK);
- for (i = 0; i < npages; i++)
- {
- pa = rt_hw_mmu_v2p(mmu_info, va);
- pa = (void *)((char *)pa - mmu_info->pv_off);
- rt_pages_free(pa, 0);
- va = (void *)((char *)va + ARCH_PAGE_SIZE);
- }
-
- __rt_hw_mmu_unmap(mmu_info, v_addr, npages);
- return -1;
+ // do not support other type to be noncache
+ err = RT_ENOSYS;
}
+ return err;
}
-void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr)
+static int _cache(uintptr_t *pte)
{
- size_t vaddr;
- size_t offset;
- int pages;
- int ret;
-
- if (!size)
+ int err = 0;
+ const uintptr_t idx_shift = 2;
+ const uintptr_t idx_mask = 0x7 << idx_shift;
+ uintptr_t entry = *pte;
+ if ((entry & idx_mask) == (NORMAL_NOCACHE_MEM << idx_shift))
{
- return 0;
- }
- offset = (size_t)v_addr & ARCH_PAGE_MASK;
- size += (offset + ARCH_PAGE_SIZE - 1);
- pages = (size >> ARCH_PAGE_SHIFT);
- if (v_addr)
- {
- vaddr = (size_t)v_addr;
- vaddr &= ~ARCH_PAGE_MASK;
- if (check_vaddr(mmu_info, (void *)vaddr, pages) != 0)
- {
- return 0;
- }
+ *pte = (entry & ~idx_mask) | (NORMAL_MEM << idx_shift);
}
else
{
- vaddr = find_vaddr(mmu_info, pages);
+ // do not support other type to be cache
+ err = -RT_ENOSYS;
}
- if (vaddr)
- {
- rt_enter_critical();
- ret = __rt_hw_mmu_map_auto(mmu_info, (void *)vaddr, pages, attr);
- if (ret == 0)
- {
- rt_hw_cpu_tlb_invalidate();
- rt_exit_critical();
- return (void *)((char *)vaddr + offset);
- }
- rt_exit_critical();
- }
- return 0;
-}
-
-void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, size_t size)
-{
- size_t va_s, va_e;
- int pages;
-
- va_s = (size_t)v_addr;
- va_e = (size_t)v_addr + size - 1;
- va_s >>= ARCH_PAGE_SHIFT;
- va_e >>= ARCH_PAGE_SHIFT;
- pages = va_e - va_s + 1;
- rt_enter_critical();
- __rt_hw_mmu_unmap(mmu_info, v_addr, pages);
- rt_hw_cpu_tlb_invalidate();
- rt_exit_critical();
+ return err;
}
-void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, size_t size, size_t attr)
-{
- void *ret;
-
- rt_mm_lock();
- ret = _rt_hw_mmu_map(mmu_info, v_addr, p_addr, size, attr);
- rt_mm_unlock();
- return ret;
-}
-
-void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr)
-{
- void *ret;
-
- rt_mm_lock();
- ret = _rt_hw_mmu_map_auto(mmu_info, v_addr, size, attr);
- rt_mm_unlock();
- return ret;
-}
-
-void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, size_t size)
-{
- rt_mm_lock();
- _rt_hw_mmu_unmap(mmu_info, v_addr, size);
- rt_mm_unlock();
-}
-#else
-
-#include <cache.h>
+static int (*control_handler[MMU_CNTL_DUMMY_END])(uintptr_t *pte) = {
+ [MMU_CNTL_CACHE] = _cache,
+ [MMU_CNTL_NONCACHE] = _noncache,
+};
-void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_size_t desc_nr)
+int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size,
+ enum rt_mmu_cntl cmd)
{
- rt_memset((void *)MMUTable, 0, sizeof(MMUTable));
- rt_memset((void *)MMUPage, 0, sizeof(MMUPage));
+ int level_shift;
+ int err = -RT_EINVAL;
+ void *vend = vaddr + size;
- /* set page table */
- for (; desc_nr > 0; --desc_nr)
+ int (*handler)(uintptr_t * pte);
+ if (cmd >= 0 && cmd < MMU_CNTL_DUMMY_END)
{
- rt_hw_mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end, mdesc->paddr_start, mdesc->attr);
- ++mdesc;
- }
-
- rt_hw_cpu_dcache_clean((void *)MMUTable, sizeof(MMUTable));
-}
-
+ handler = control_handler[cmd];
-void rt_hw_mmu_init(void)
-{
- unsigned long reg_val;
-
- reg_val = 0x00447fUL;
- __asm__ volatile("msr mair_el1, %0"::"r"(reg_val));
-
- rt_hw_isb();
-
- reg_val = (16UL << 0) /* t0sz 48bit */
- | (0UL << 6) /* reserved */
- | (0UL << 7) /* epd0 */
- | (3UL << 8) /* t0 wb cacheable */
- | (3UL << 10) /* inner shareable */
- | (2UL << 12) /* t0 outer shareable */
- | (0UL << 14) /* t0 4K */
- | (16UL << 16) /* t1sz 48bit */
- | (0UL << 22) /* define asid use ttbr0.asid */
- | (0UL << 23) /* epd1 */
- | (3UL << 24) /* t1 inner wb cacheable */
- | (3UL << 26) /* t1 outer wb cacheable */
- | (2UL << 28) /* t1 outer shareable */
- | (2UL << 30) /* t1 4k */
- | (1UL << 32) /* 001b 64GB PA */
- | (0UL << 35) /* reserved */
- | (1UL << 36) /* as: 0:8bit 1:16bit */
- | (0UL << 37) /* tbi0 */
- | (0UL << 38); /* tbi1 */
- __asm__ volatile("msr tcr_el1, %0"::"r"(reg_val));
-
- rt_hw_isb();
-
- __asm__ volatile ("mrs %0, sctlr_el1":"=r"(reg_val));
-
- reg_val |= 1 << 2; /* enable dcache */
- reg_val |= 1 << 0; /* enable mmu */
-
- __asm__ volatile (
- "msr ttbr0_el1, %0\n\r"
- "msr sctlr_el1, %1\n\r"
- "dsb sy\n\r"
- "isb sy\n\r"
- ::"r"(MMUTable), "r"(reg_val) :"memory");
-
- rt_hw_cpu_tlb_invalidate();
-}
-#endif
-
-void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr)
-{
- int level;
- unsigned long va = (unsigned long)v_addr;
- unsigned long pa;
- unsigned long *cur_lv_tbl;
- unsigned long page;
- unsigned long off;
- unsigned long off_addr;
- int level_shift = MMU_ADDRESS_BITS;
-
- if (!mmu_info)
- {
- return (void *)0;
- }
- cur_lv_tbl = mmu_info->vtable;
- for (level = 0; level < MMU_TBL_PAGE_4k_LEVEL; level++)
- {
- off = (va >> level_shift);
- off &= MMU_LEVEL_MASK;
- if (!(cur_lv_tbl[off] & MMU_TYPE_USED))
- {
- return (void *)0;
- }
- page = cur_lv_tbl[off];
- if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK)
+ while (vaddr < vend)
{
- off_addr = va & ((1UL << level_shift) - 1);
- pa = (page & MMU_ADDRESS_MASK);
- pa += off_addr;
- return (void *)pa;
+ uintptr_t *pte = _query(aspace, vaddr, &level_shift);
+ void *range_end = vaddr + (1ul << level_shift);
+ RT_ASSERT(range_end <= vend);
+
+ if (pte)
+ {
+ err = handler(pte);
+ RT_ASSERT(err == RT_EOK);
+ }
+ vaddr = range_end;
}
- cur_lv_tbl = (unsigned long *)(page & MMU_ADDRESS_MASK);
- cur_lv_tbl = (unsigned long *)((unsigned long)cur_lv_tbl - PV_OFFSET);
- level_shift -= MMU_LEVEL_SHIFT;
}
- /* now is level MMU_TBL_PAGE_4k_LEVEL */
- off = (va >> ARCH_PAGE_SHIFT);
- off &= MMU_LEVEL_MASK;
- page = cur_lv_tbl[off];
- if (!(page & MMU_TYPE_USED))
+ else
{
- return (void *)0;
+ err = -RT_ENOSYS;
}
- pa = (page & MMU_ADDRESS_MASK);
- pa += (va & ARCH_PAGE_MASK);
- return (void *)pa;
-}
-void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr)
-{
- void *ret;
-
- rt_mm_lock();
- ret = _rt_hw_mmu_v2p(mmu_info, v_addr);
- rt_mm_unlock();
- return ret;
+ return err;
}
-
-void rt_hw_mmu_setup_early(unsigned long *tbl0, unsigned long *tbl1, unsigned long size, unsigned long pv_off)
+void rt_hw_mmu_setup_early(unsigned long *tbl0, unsigned long *tbl1,
+ unsigned long size, unsigned long pv_off)
{
int ret;
unsigned long va = KERNEL_VADDR_START;
@@ -1015,15 +665,15 @@ void rt_hw_mmu_setup_early(unsigned long *tbl0, unsigned long *tbl1, unsigned lo
unsigned long normal_attr = MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_MEM);
/* clean the first two pages */
- mmu_memset((char *)tbl0, 0, ARCH_PAGE_SIZE);
- mmu_memset((char *)tbl1, 0, ARCH_PAGE_SIZE);
+ rt_memset((char *)tbl0, 0, ARCH_PAGE_SIZE);
+ rt_memset((char *)tbl1, 0, ARCH_PAGE_SIZE);
- ret = armv8_init_map_2M(tbl1, va, va + pv_off, count, normal_attr);
+ ret = _init_map_2M(tbl1, va, va + pv_off, count, normal_attr);
if (ret != 0)
{
while (1);
}
- ret = armv8_init_map_2M(tbl0, va + pv_off, va + pv_off, count, normal_attr);
+ ret = _init_map_2M(tbl0, va + pv_off, va + pv_off, count, normal_attr);
if (ret != 0)
{
while (1);
diff --git a/libcpu/aarch64/common/mmu.h b/libcpu/aarch64/common/mmu.h
index 0e61eeac70..6dc8cdca31 100644
--- a/libcpu/aarch64/common/mmu.h
+++ b/libcpu/aarch64/common/mmu.h
@@ -11,6 +11,7 @@
#define __MMU_H_
#include <rtthread.h>
+#include <mm_aspace.h>
/* normal memory wra mapping type */
#define NORMAL_MEM 0
@@ -25,6 +26,7 @@ struct mem_desc
unsigned long vaddr_end;
unsigned long paddr_start;
unsigned long attr;
+ struct rt_varea varea;
};
#define MMU_AF_SHIFT 10
@@ -37,60 +39,17 @@ struct mem_desc
#define MMU_AP_KRUN 2UL /* kernel r, user none */
#define MMU_AP_KRUR 3UL /* kernel r, user r */
-#define MMU_MAP_K_RO (\
- (0x1UL << MMU_AF_SHIFT) |\
- (0x2UL << MMU_SHARED_SHIFT) |\
- (MMU_AP_KRUN << MMU_AP_SHIFT) |\
- (NORMAL_MEM << MMU_MA_SHIFT)\
- )
-#define MMU_MAP_K_RWCB (\
- (0x1UL << MMU_AF_SHIFT) |\
- (0x2UL << MMU_SHARED_SHIFT) |\
- (MMU_AP_KAUN << MMU_AP_SHIFT) |\
- (NORMAL_MEM << MMU_MA_SHIFT)\
- )
-#define MMU_MAP_K_RW (\
- (0x1UL << MMU_AF_SHIFT) |\
- (0x2UL << MMU_SHARED_SHIFT) |\
- (MMU_AP_KAUN << MMU_AP_SHIFT) |\
- (NORMAL_NOCACHE_MEM << MMU_MA_SHIFT)\
- )
-#define MMU_MAP_K_DEVICE (\
- (0x1UL << MMU_AF_SHIFT) |\
- (0x2UL << MMU_SHARED_SHIFT) |\
- (MMU_AP_KAUN << MMU_AP_SHIFT) |\
- (DEVICE_MEM << MMU_MA_SHIFT)\
- )
-#define MMU_MAP_U_RO (\
- (0x1UL << MMU_AF_SHIFT) |\
- (0x2UL << MMU_SHARED_SHIFT) |\
- (MMU_AP_KRUR << MMU_AP_SHIFT) |\
- (NORMAL_NOCACHE_MEM << MMU_MA_SHIFT)\
- )
-#define MMU_MAP_U_RWCB (\
- (0x1UL << MMU_AF_SHIFT) |\
- (0x2UL << MMU_SHARED_SHIFT) |\
- (MMU_AP_KAUA << MMU_AP_SHIFT) |\
- (NORMAL_MEM << MMU_MA_SHIFT)\
- )
-#define MMU_MAP_U_RW (\
- (0x1UL << MMU_AF_SHIFT) |\
- (0x2UL << MMU_SHARED_SHIFT) |\
- (MMU_AP_KAUA << MMU_AP_SHIFT) |\
- (NORMAL_NOCACHE_MEM << MMU_MA_SHIFT)\
- )
-#define MMU_MAP_U_DEVICE (\
- (0x1UL << MMU_AF_SHIFT) |\
- (0x2UL << MMU_SHARED_SHIFT) |\
- (MMU_AP_KAUA << MMU_AP_SHIFT) |\
- (DEVICE_MEM << MMU_MA_SHIFT)\
- )
-#define MMU_MAP_CUSTOM(ap, mtype) (\
- (0x1UL << MMU_AF_SHIFT) |\
- (0x2UL << MMU_SHARED_SHIFT) |\
- ((ap) << MMU_AP_SHIFT) |\
- ((mtype) << MMU_MA_SHIFT)\
- )
+#define MMU_MAP_CUSTOM(ap, mtype) \
+ ((0x1UL << MMU_AF_SHIFT) | (0x2UL << MMU_SHARED_SHIFT) | \
+ ((ap) << MMU_AP_SHIFT) | ((mtype) << MMU_MA_SHIFT))
+#define MMU_MAP_K_RO MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_MEM)
+#define MMU_MAP_K_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_MEM)
+#define MMU_MAP_K_RW MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_NOCACHE_MEM)
+#define MMU_MAP_K_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUN, DEVICE_MEM)
+#define MMU_MAP_U_RO MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_NOCACHE_MEM)
+#define MMU_MAP_U_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_MEM)
+#define MMU_MAP_U_RW MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_NOCACHE_MEM)
+#define MMU_MAP_U_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUA, DEVICE_MEM)
#define ARCH_SECTION_SHIFT 21
#define ARCH_SECTION_SIZE (1 << ARCH_SECTION_SHIFT)
@@ -102,6 +61,7 @@ struct mem_desc
#define ARCH_PAGE_TBL_SIZE (1 << ARCH_PAGE_TBL_SHIFT)
#define ARCH_PAGE_TBL_MASK (ARCH_PAGE_TBL_SIZE - 1)
+#define ARCH_VADDR_WIDTH 48
#define ARCH_ADDRESS_WIDTH_BITS 64
#define MMU_MAP_ERROR_VANOTALIGN -1
@@ -109,37 +69,48 @@ struct mem_desc
#define MMU_MAP_ERROR_NOPAGE -3
#define MMU_MAP_ERROR_CONFLICT -4
-typedef struct
-{
- size_t *vtable;
- size_t vstart;
- size_t vend;
- size_t pv_off;
-} rt_mmu_info;
+#define ARCH_MAP_FAILED ((void *)0x1ffffffffffff)
-void rt_hw_mmu_setup_early(unsigned long *tbl0, unsigned long *tbl1, unsigned long size, unsigned long pv_off);
-void rt_hw_mmu_setup(struct mem_desc *mdesc, int desc_nr);
+struct rt_aspace;
-int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size_t *vtable, size_t pv_off);
-int rt_hw_mmu_ioremap_init(rt_mmu_info *mmu_info, void* v_address, size_t size);
+void rt_hw_mmu_ktbl_set(unsigned long tbl);
+void rt_hw_mmu_setup_early(unsigned long *tbl0, unsigned long *tbl1,
+ unsigned long size, unsigned long pv_off);
+void rt_hw_mmu_setup(struct rt_aspace *aspace, struct mem_desc *mdesc,
+ int desc_nr);
-#ifdef RT_USING_SMART
-void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr);
-void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr);
-#else
-void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr);
-#endif
+int rt_hw_mmu_map_init(struct rt_aspace *aspace, void *v_address,
+ rt_size_t size, rt_size_t *vtable, rt_size_t pv_off);
+void *rt_hw_mmu_map(struct rt_aspace *aspace, void *v_addr, void *p_addr,
+ size_t size, size_t attr);
+void rt_hw_mmu_unmap(struct rt_aspace *aspace, void *v_addr, size_t size);
+void rt_hw_aspace_switch(struct rt_aspace *aspace);
+void *rt_hw_mmu_v2p(struct rt_aspace *aspace, void *vaddr);
+void rt_hw_mmu_kernel_map_init(struct rt_aspace *aspace, rt_size_t vaddr_start,
+ rt_size_t size);
+void rt_hw_mmu_ktbl_set(unsigned long tbl);
-void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size);
-void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr);
+static inline void *rt_hw_mmu_tbl_get()
+{
+ uintptr_t tbl;
+ __asm__ volatile("MRS %0, TTBR0_EL1" : "=r"(tbl));
+ return (void *)(tbl & ((1ul << 48) - 2));
+}
-void rt_hw_mmu_ktbl_set(unsigned long tbl);
-void *rt_hw_mmu_tbl_get();
-void rt_hw_mmu_switch(void *mmu_table);
+static inline void *_rt_kmem_v2p(void *vaddr)
+{
+ return rt_hw_mmu_v2p(&rt_kernel_space, vaddr);
+}
-void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_size_t desc_nr);
-void rt_hw_mmu_init(void);
+static inline void *rt_kmem_v2p(void *vaddr)
+{
+ MM_PGTBL_LOCK(&rt_kernel_space);
+ void *paddr = _rt_kmem_v2p(vaddr);
+ MM_PGTBL_UNLOCK(&rt_kernel_space);
+ return paddr;
+}
-extern rt_mmu_info mmu_info;
+int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size,
+ enum rt_mmu_cntl cmd);
#endif
diff --git a/libcpu/aarch64/common/tlb.h b/libcpu/aarch64/common/tlb.h
new file mode 100644
index 0000000000..088af488fc
--- /dev/null
+++ b/libcpu/aarch64/common/tlb.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-11-28 WangXiaoyao the first version
+ */
+#ifndef __TLB_H__
+#define __TLB_H__
+
+#include <rtthread.h>
+#include <stddef.h>
+#include <stdint.h>
+#include "mm_aspace.h"
+#include "mmu.h"
+
+#define TLBI_ARG(addr, asid) \
+ ({ \
+ uintptr_t arg = (uintptr_t)(addr) >> 12; \
+ arg &= (1ull << 44) - 1; \
+ arg |= (uintptr_t)(asid) << 48; \
+ (void *)arg; \
+ })
+
+static inline void rt_hw_tlb_invalidate_all(void)
+{
+ __asm__ volatile(
+ // ensure updates to pte completed
+ "dsb ishst\n"
+ "tlbi vmalle1is\n"
+ "dsb ish\n"
+ // after tlb in new context, refresh inst
+ "isb\n" ::
+ : "memory");
+}
+
+static inline void rt_hw_tlb_invalidate_all_local(void)
+{
+ __asm__ volatile(
+ // ensure updates to pte completed
+ "dsb nshst\n"
+ "tlbi vmalle1is\n"
+ "dsb nsh\n"
+ // after tlb in new context, refresh inst
+ "isb\n" ::
+ : "memory");
+}
+
+static inline void rt_hw_tlb_invalidate_aspace(rt_aspace_t aspace)
+{
+ rt_hw_tlb_invalidate_all_local();
+}
+
+static inline void rt_hw_tlb_invalidate_page(rt_aspace_t aspace, void *start)
+{
+ start = TLBI_ARG(start, 0);
+ __asm__ volatile(
+ "dsb ishst\n"
+ "tlbi vaae1is, %0\n"
+ "dsb ish\n"
+ "isb\n" ::"r"(start)
+ : "memory");
+}
+
+static inline void rt_hw_tlb_invalidate_range(rt_aspace_t aspace, void *start,
+ size_t size, size_t stride)
+{
+ if (size < ARCH_PAGE_SIZE)
+ {
+ rt_hw_tlb_invalidate_page(aspace, start);
+ }
+ else
+ {
+ rt_hw_tlb_invalidate_aspace(aspace);
+ }
+}
+
+#endif /* __TLB_H__ */
diff --git a/libcpu/aarch64/common/trap.c b/libcpu/aarch64/common/trap.c
index 0a449efeb8..0a2dd2e9ed 100644
--- a/libcpu/aarch64/common/trap.c
+++ b/libcpu/aarch64/common/trap.c
@@ -14,6 +14,7 @@
#include <armv8.h>
#include "interrupt.h"
+#include "mm_fault.h"
#include <backtrace.h>
@@ -48,6 +49,29 @@ void check_user_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *info)
}
}
+int _get_type(unsigned long esr)
+{
+ int ret;
+ int fsc = esr & 0x3f;
+ switch (fsc)
+ {
+ case 0x4:
+ case 0x5:
+ case 0x6:
+ case 0x7:
+ ret = MM_FAULT_TYPE_PAGE_FAULT;
+ break;
+ case 0x9:
+ case 0xa:
+ case 0xb:
+ ret = MM_FAULT_TYPE_ACCESS_FAULT;
+ break;
+ default:
+ ret = MM_FAULT_TYPE_GENERIC;
+ }
+ return ret;
+}
+
int check_user_stack(unsigned long esr, struct rt_hw_exp_stack *regs)
{
unsigned char ec;
@@ -55,19 +79,36 @@ int check_user_stack(unsigned long esr, struct rt_hw_exp_stack *regs)
int ret = 0;
ec = (unsigned char)((esr >> 26) & 0x3fU);
+ enum rt_mm_fault_op fault_op;
+ enum rt_mm_fault_type fault_type;
switch (ec)
{
case 0x20:
+ fault_op = MM_FAULT_OP_EXECUTE;
+ fault_type = _get_type(esr);
+ break;
case 0x21:
case 0x24:
+ fault_op = MM_FAULT_OP_WRITE;
+ fault_type = _get_type(esr);
+ break;
+ default:
+ fault_op = 0;
+ break;
+ }
+
+ if (fault_op)
+ {
asm volatile("mrs %0, far_el1":"=r"(dfar));
- if (arch_expand_user_stack(dfar))
+ struct rt_mm_fault_msg msg = {
+ .fault_op = fault_op,
+ .fault_type = fault_type,
+ .vaddr = dfar,
+ };
+ if (rt_mm_fault_try_fix(&msg))
{
ret = 1;
}
- break;
- default:
- break;
}
return ret;
}
diff --git a/libcpu/aarch64/cortex-a/entry_point.S b/libcpu/aarch64/cortex-a/entry_point.S
index ae3fa02ccd..89c383a1e5 100644
--- a/libcpu/aarch64/cortex-a/entry_point.S
+++ b/libcpu/aarch64/cortex-a/entry_point.S
@@ -91,10 +91,11 @@ __start:
msr cpacr_el1, x1
/* clear bss */
- ldr x1, =__bss_start /* get bss start address */
- ldr x2, =__bss_end
+ adrp x1, __bss_start /* get bss start address */
+ add x1, x1, #:lo12:__bss_start
+ adrp x2, __bss_end
+ add x1, x1, #:lo12:__bss_end
sub x2, x2, x1 /* get bss size */
- add x1, x1, x9
and x3, x2, #7 /* x3 is < 7 */
ldr x4, =~0x7
@@ -140,14 +141,14 @@ __start:
orr x1, x1, #(1 << 0) /* M */
msr sctlr_el1, x1 /* enable MMU */
- dsb sy
- isb sy
+ dsb ish
+ isb
ic ialluis /* Invalidate all instruction caches in Inner Shareable domain to Point of Unification */
- dsb sy
- isb sy
+ dsb ish
+ isb
tlbi vmalle1 /* Invalidate all stage 1 translations used at EL1 with the current VMID */
- dsb sy
- isb sy
+ dsb ish
+ isb
ret
after_mmu_enable:
diff --git a/libcpu/arm/cortex-a/context_gcc.S b/libcpu/arm/cortex-a/context_gcc.S
index c4531dede5..98080de5c1 100644
--- a/libcpu/arm/cortex-a/context_gcc.S
+++ b/libcpu/arm/cortex-a/context_gcc.S
@@ -53,7 +53,7 @@ rt_hw_context_switch_to:
#ifdef RT_USING_SMART
bl rt_thread_self
mov r4, r0
- bl lwp_mmu_switch
+ bl lwp_aspace_switch
mov r0, r4
bl lwp_user_setting_restore
#endif
@@ -116,7 +116,7 @@ rt_hw_context_switch:
#ifdef RT_USING_SMART
bl rt_thread_self
mov r4, r0
- bl lwp_mmu_switch
+ bl lwp_aspace_switch
mov r0, r4
bl lwp_user_setting_restore
#endif
diff --git a/libcpu/arm/cortex-a/cpuport.h b/libcpu/arm/cortex-a/cpuport.h
index ab68d1e311..e881da9147 100644
--- a/libcpu/arm/cortex-a/cpuport.h
+++ b/libcpu/arm/cortex-a/cpuport.h
@@ -10,6 +10,8 @@
#ifndef CPUPORT_H__
#define CPUPORT_H__
+#include <rtthread.h>
+
/* the exception stack without VFP registers */
struct rt_hw_exp_stack
{
diff --git a/libcpu/arm/cortex-a/interrupt.c b/libcpu/arm/cortex-a/interrupt.c
index fb257cc2de..d0cc89d6e2 100644
--- a/libcpu/arm/cortex-a/interrupt.c
+++ b/libcpu/arm/cortex-a/interrupt.c
@@ -70,8 +70,8 @@ void rt_hw_interrupt_init(void)
/* initialize ARM GIC */
#ifdef RT_USING_SMART
- gic_dist_base = (uint32_t)rt_hw_mmu_map(&mmu_info, 0, (void*)platform_get_gic_dist_base(), 0x2000, MMU_MAP_K_RW);
- gic_cpu_base = (uint32_t)rt_hw_mmu_map(&mmu_info, 0, (void*)platform_get_gic_cpu_base(), 0x1000, MMU_MAP_K_RW);
+ gic_dist_base = (uint32_t)rt_ioremap((void*)platform_get_gic_dist_base(), 0x2000);
+ gic_cpu_base = (uint32_t)rt_ioremap((void*)platform_get_gic_cpu_base(), 0x1000);
#else
gic_dist_base = platform_get_gic_dist_base();
gic_cpu_base = platform_get_gic_cpu_base();
@@ -100,7 +100,8 @@ void rt_hw_interrupt_init(void)
/* initialize ARM GIC */
#ifdef RT_USING_SMART
- gic_dist_base = (uint32_t)rt_hw_mmu_map(&mmu_info, 0, (void*)platform_get_gic_dist_base(), 0x2000, MMU_MAP_K_RW);
+ gic_dist_base = (uint32_t)rt_ioremap((void*)platform_get_gic_dist_base(), 0x2000);
+ gic_cpu_base = (uint32_t)rt_ioremap((void*)platform_get_gic_cpu_base(), 0x1000);
#else
gic_dist_base = platform_get_gic_dist_base();
#endif
diff --git a/libcpu/arm/cortex-a/mmu.c b/libcpu/arm/cortex-a/mmu.c
index 19fd0f10d2..150dd98b27 100644
--- a/libcpu/arm/cortex-a/mmu.c
+++ b/libcpu/arm/cortex-a/mmu.c
@@ -12,52 +12,23 @@
#include <rtthread.h>
#include <board.h>
-
#include "cp15.h"
+#include "mm_page.h"
#include "mmu.h"
+#include <mm_aspace.h>
+#include <tlb.h>
#ifdef RT_USING_SMART
#include <lwp_mm.h>
-#include "page.h"
+#include <lwp_arch.h>
+#include "ioremap.h"
+#else
+#define KERNEL_VADDR_START 0
+#define PV_OFFSET 0
#endif
/* level1 page table, each entry for 1MB memory. */
-volatile unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024)));
-
-#ifndef RT_USING_SMART
-static rt_mutex_t mm_lock = RT_NULL;
-
-void rt_mm_lock(void)
-{
- if (rt_thread_self())
- {
- if (!mm_lock)
- {
- mm_lock = rt_mutex_create("mm_lock", RT_IPC_FLAG_FIFO);
- }
- if (mm_lock)
- {
- rt_mutex_take(mm_lock, RT_WAITING_FOREVER);
- }
- }
-}
-
-void rt_mm_unlock(void)
-{
- if (rt_thread_self())
- {
- if (mm_lock)
- {
- rt_mutex_release(mm_lock);
- }
- }
-}
-#endif
-
-void rt_hw_cpu_tlb_invalidate(void)
-{
- asm volatile ("mcr p15, 0, r0, c8, c7, 0\ndsb\nisb" ::: "memory");
-}
+volatile unsigned long MMUTable[4 * 1024] __attribute__((aligned(16 * 1024)));
unsigned long rt_hw_set_domain_register(unsigned long domain_val)
{
@@ -69,117 +40,8 @@ unsigned long rt_hw_set_domain_register(unsigned long domain_val)
return old_domain;
}
-/* dump 2nd level page table */
-void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
-{
- int i;
- int fcnt = 0;
-
- for (i = 0; i < 256; i++)
- {
- rt_uint32_t pte2 = ptb[i];
- if ((pte2 & 0x3) == 0)
- {
- if (fcnt == 0)
- rt_kprintf(" ");
- rt_kprintf("%04x: ", i);
- fcnt++;
- if (fcnt == 16)
- {
- rt_kprintf("fault\n");
- fcnt = 0;
- }
- continue;
- }
- if (fcnt != 0)
- {
- rt_kprintf("fault\n");
- fcnt = 0;
- }
-
- rt_kprintf(" %04x: %x: ", i, pte2);
- if ((pte2 & 0x3) == 0x1)
- {
- rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n",
- ((pte2 >> 7) | (pte2 >> 4))& 0xf,
- (pte2 >> 15) & 0x1,
- ((pte2 >> 10) | (pte2 >> 2)) & 0x1f);
- }
- else
- {
- rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n",
- ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1,
- ((pte2 >> 4) | (pte2 >> 2)) & 0x1f);
- }
- }
-}
-
-void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb)
-{
- int i;
- int fcnt = 0;
-
- rt_kprintf("page table@%p\n", ptb);
- for (i = 0; i < 1024*4; i++)
- {
- rt_uint32_t pte1 = ptb[i];
- if ((pte1 & 0x3) == 0)
- {
- rt_kprintf("%03x: ", i);
- fcnt++;
- if (fcnt == 16)
- {
- rt_kprintf("fault\n");
- fcnt = 0;
- }
- continue;
- }
- if (fcnt != 0)
- {
- rt_kprintf("fault\n");
- fcnt = 0;
- }
-
- rt_kprintf("%03x: %08x: ", i, pte1);
- if ((pte1 & 0x3) == 0x3)
- {
- rt_kprintf("LPAE\n");
- }
- else if ((pte1 & 0x3) == 0x1)
- {
- rt_kprintf("pte,ns:%d,domain:%d\n",
- (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf);
- /*
- *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000)
- * - 0x80000000 + 0xC0000000));
- */
- }
- else if (pte1 & (1 << 18))
- {
- rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n",
- (pte1 >> 19) & 0x1,
- ((pte1 >> 13) | (pte1 >> 10))& 0xf,
- (pte1 >> 4) & 0x1,
- ((pte1 >> 10) | (pte1 >> 2)) & 0x1f);
- }
- else
- {
- rt_kprintf("section,ns:%d,ap:%x,"
- "xn:%d,texcb:%02x,domain:%d\n",
- (pte1 >> 19) & 0x1,
- ((pte1 >> 13) | (pte1 >> 10))& 0xf,
- (pte1 >> 4) & 0x1,
- (((pte1 & (0x7 << 12)) >> 10) |
- ((pte1 & 0x0c) >> 2)) & 0x1f,
- (pte1 >> 5) & 0xf);
- }
- }
-}
-
-void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart,
- rt_uint32_t vaddrEnd,
- rt_uint32_t paddrStart,
- rt_uint32_t attr)
+void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd,
+ rt_uint32_t paddrStart, rt_uint32_t attr)
{
volatile rt_uint32_t *pTT;
volatile int i, nSec;
@@ -224,11 +86,11 @@ void rt_hw_mmu_init(void)
rt_hw_cpu_dcache_enable();
}
-int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size_t *vtable, size_t pv_off)
+int rt_hw_mmu_map_init(struct rt_aspace *aspace, void* v_address, size_t size, size_t *vtable, size_t pv_off)
{
size_t l1_off, va_s, va_e;
- if (!mmu_info || !vtable)
+ if (!aspace || !vtable)
{
return -1;
}
@@ -259,15 +121,20 @@ int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size
}
}
- mmu_info->vtable = vtable;
- mmu_info->vstart = va_s;
- mmu_info->vend = va_e;
- mmu_info->pv_off = pv_off;
+#ifdef RT_USING_SMART
+ rt_aspace_init(&rt_kernel_space, (void *)USER_VADDR_TOP, 0 - USER_VADDR_TOP, vtable);
+ rt_ioremap_start = v_address;
+ rt_ioremap_size = size;
+ rt_mpr_start = rt_ioremap_start - rt_mpr_size;
+#else
+ rt_aspace_init(&rt_kernel_space, (void *)0x1000, 0 - 0x1000, vtable);
+ rt_mpr_start = (void *)0 - rt_mpr_size;
+#endif
return 0;
}
-int rt_hw_mmu_ioremap_init(rt_mmu_info *mmu_info, void* v_address, size_t size)
+int rt_hw_mmu_ioremap_init(rt_aspace_t aspace, void* v_address, size_t size)
{
#ifdef RT_IOREMAP_LATE
size_t loop_va;
@@ -296,7 +163,7 @@ int rt_hw_mmu_ioremap_init(rt_mmu_info *mmu_info, void* v_address, size_t size)
while (sections--)
{
l1_off = (loop_va >> ARCH_SECTION_SHIFT);
- mmu_l1 = (size_t*)mmu_info->vtable + l1_off;
+ mmu_l1 = (size_t*)aspace->page_table + l1_off;
RT_ASSERT((*mmu_l1 & ARCH_MMU_USED_MASK) == 0);
mmu_l2 = (size_t*)rt_pages_alloc(0);
@@ -306,7 +173,7 @@ int rt_hw_mmu_ioremap_init(rt_mmu_info *mmu_info, void* v_address, size_t size)
/* cache maintain */
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l2, ARCH_PAGE_TBL_SIZE);
- *mmu_l1 = (((size_t)mmu_l2 + mmu_info->pv_off) | 0x1);
+ *mmu_l1 = (((size_t)mmu_l2 + PV_OFFSET) | 0x1);
/* cache maintain */
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l1, 4);
}
@@ -323,427 +190,184 @@ int rt_hw_mmu_ioremap_init(rt_mmu_info *mmu_info, void* v_address, size_t size)
return 0;
}
-#ifdef RT_USING_SMART
-static size_t find_vaddr(rt_mmu_info *mmu_info, int pages)
-{
- size_t l1_off, l2_off;
- size_t *mmu_l1, *mmu_l2;
- size_t find_off = 0;
- size_t find_va = 0;
- int n = 0;
-
- if (!pages)
- {
- return 0;
- }
- if (!mmu_info)
- {
- return 0;
- }
- for (l1_off = mmu_info->vstart; l1_off <= mmu_info->vend; l1_off++)
- {
- mmu_l1 = (size_t*)mmu_info->vtable + l1_off;
- if (*mmu_l1 & ARCH_MMU_USED_MASK)
- {
- mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
- for (l2_off = 0; l2_off < (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE); l2_off++)
- {
- if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK)
- {
- /* in use */
- n = 0;
- }
- else
- {
- if (!n)
- {
- find_va = l1_off;
- find_off = l2_off;
- }
- n++;
- if (n >= pages)
- {
- return (find_va << ARCH_SECTION_SHIFT) + (find_off << ARCH_PAGE_SHIFT);
- }
- }
- }
- }
- else
- {
- if (!n)
- {
- find_va = l1_off;
- find_off = 0;
- }
- n += (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE);
- if (n >= pages)
- {
- return (find_va << ARCH_SECTION_SHIFT) + (find_off << ARCH_PAGE_SHIFT);
- }
- }
- }
- return 0;
-}
-static int check_vaddr(rt_mmu_info *mmu_info, void *va, int pages)
+static void _kenrel_unmap_4K(unsigned long *lv0_tbl, void *v_addr)
{
- size_t loop_va = (size_t)va & ~ARCH_PAGE_MASK;
+ size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK;
size_t l1_off, l2_off;
size_t *mmu_l1, *mmu_l2;
- if (!pages)
- {
- return -1;
- }
+ l1_off = (loop_va >> ARCH_SECTION_SHIFT);
- if (!mmu_info)
- {
- return -1;
- }
+ l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
+ mmu_l1 = (size_t *)lv0_tbl + l1_off;
- l1_off = ((size_t)va >> ARCH_SECTION_SHIFT);
- if (l1_off < mmu_info->vstart || l1_off > mmu_info->vend)
+ if (*mmu_l1 & ARCH_MMU_USED_MASK)
{
- return -1;
+ mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - PV_OFFSET);
}
- l1_off += ((pages << ARCH_PAGE_SHIFT) >> ARCH_SECTION_SHIFT);
- if (l1_off < mmu_info->vstart || l1_off > mmu_info->vend + 1)
+ else
{
- return -1;
+ return;
}
- while (pages--)
+ if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK)
{
- l1_off = (loop_va >> ARCH_SECTION_SHIFT);
- l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
- mmu_l1 = (size_t*)mmu_info->vtable + l1_off;
+ *(mmu_l2 + l2_off) = 0;
+ /* cache maintain */
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l2 + l2_off, 4);
- if (*mmu_l1 & ARCH_MMU_USED_MASK)
+ if (rt_pages_free(mmu_l2, 0))
{
- mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
- if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK)
- {
- return -1;
- }
+ *mmu_l1 = 0;
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l1, 4);
}
- loop_va += ARCH_PAGE_SIZE;
}
- return 0;
+ loop_va += ARCH_PAGE_SIZE;
}
-static void __rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t npages)
+static int _kenrel_map_4K(unsigned long *lv0_tbl, void *v_addr, void *p_addr,
+ size_t attr)
{
size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK;
+ size_t loop_pa = (size_t)p_addr & ~ARCH_PAGE_MASK;
size_t l1_off, l2_off;
size_t *mmu_l1, *mmu_l2;
- if (!mmu_info)
+ l1_off = (loop_va >> ARCH_SECTION_SHIFT);
+ l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
+ mmu_l1 = (size_t *)lv0_tbl + l1_off;
+
+ if (*mmu_l1 & ARCH_MMU_USED_MASK)
{
- return;
+ mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - PV_OFFSET);
+ rt_page_ref_inc(mmu_l2, 0);
}
-
- while (npages--)
+ else
{
- l1_off = (loop_va >> ARCH_SECTION_SHIFT);
- if (l1_off < mmu_info->vstart || l1_off > mmu_info->vend)
+ mmu_l2 = (size_t *)rt_pages_alloc(0);
+ if (mmu_l2)
{
- return;
- }
-
- l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
- mmu_l1 = (size_t*)mmu_info->vtable + l1_off;
+ rt_memset(mmu_l2, 0, ARCH_PAGE_TBL_SIZE * 2);
+ /* cache maintain */
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l2, ARCH_PAGE_TBL_SIZE);
- if (*mmu_l1 & ARCH_MMU_USED_MASK)
- {
- mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
+ *mmu_l1 = (((size_t)mmu_l2 + PV_OFFSET) | 0x1);
+ /* cache maintain */
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l1, 4);
}
else
{
- return;
+ /* error, quit */
+ return -1;
}
+ }
- if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK)
- {
- *(mmu_l2 + l2_off) = 0;
- /* cache maintain */
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l2 + l2_off, 4);
+ *(mmu_l2 + l2_off) = (loop_pa | attr);
+ /* cache maintain */
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l2 + l2_off, 4);
- if (rt_pages_free(mmu_l2, 0))
- {
- *mmu_l1 = 0;
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l1, 4);
- }
- }
- loop_va += ARCH_PAGE_SIZE;
- }
+ loop_va += ARCH_PAGE_SIZE;
+ loop_pa += ARCH_PAGE_SIZE;
+
+ return 0;
}
-static int __rt_hw_mmu_map(rt_mmu_info *mmu_info, void* v_addr, void* p_addr, size_t npages, size_t attr)
+void *rt_hw_mmu_map(rt_aspace_t aspace, void *v_addr, void *p_addr, size_t size,
+ size_t attr)
{
- size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK;
- size_t loop_pa = (size_t)p_addr & ~ARCH_PAGE_MASK;
- size_t l1_off, l2_off;
- size_t *mmu_l1, *mmu_l2;
-
- if (!mmu_info)
- {
- return -1;
- }
+ int ret = -1;
+ void *unmap_va = v_addr;
+ size_t npages = size >> ARCH_PAGE_SHIFT;
+ // TODO trying with HUGEPAGE here
while (npages--)
{
- l1_off = (loop_va >> ARCH_SECTION_SHIFT);
- l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
- mmu_l1 = (size_t*)mmu_info->vtable + l1_off;
-
- if (*mmu_l1 & ARCH_MMU_USED_MASK)
- {
- mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
- rt_page_ref_inc(mmu_l2, 0);
- }
- else
+ ret = _kenrel_map_4K(aspace->page_table, v_addr, p_addr, attr);
+ if (ret != 0)
{
- mmu_l2 = (size_t*)rt_pages_alloc(0);
- if (mmu_l2)
+ /* error, undo map */
+ while (unmap_va != v_addr)
{
- rt_memset(mmu_l2, 0, ARCH_PAGE_TBL_SIZE * 2);
- /* cache maintain */
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l2, ARCH_PAGE_TBL_SIZE);
+ rt_enter_critical();
+ _kenrel_unmap_4K(aspace->page_table, (void *)unmap_va);
+ rt_exit_critical();
- *mmu_l1 = (((size_t)mmu_l2 + mmu_info->pv_off) | 0x1);
- /* cache maintain */
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l1, 4);
- }
- else
- {
- /* error, unmap and quit */
- __rt_hw_mmu_unmap(mmu_info, v_addr, npages);
- return -1;
+ unmap_va += ARCH_PAGE_SIZE;
}
+ break;
}
+ v_addr += ARCH_PAGE_SIZE;
+ p_addr += ARCH_PAGE_SIZE;
+ }
- *(mmu_l2 + l2_off) = (loop_pa | attr);
- /* cache maintain */
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l2 + l2_off, 4);
-
- loop_va += ARCH_PAGE_SIZE;
- loop_pa += ARCH_PAGE_SIZE;
+ if (ret == 0)
+ {
+ return v_addr;
}
- return 0;
+ return NULL;
}
-void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr)
+void rt_hw_mmu_unmap(rt_aspace_t aspace, void *v_addr, size_t size)
{
- size_t pa_s, pa_e;
- size_t vaddr;
- int pages;
- int ret;
+ // caller guarantee that v_addr & size are page aligned
+ size_t npages = size >> ARCH_PAGE_SHIFT;
- if (!size)
- {
- return 0;
- }
- pa_s = (size_t)p_addr;
- pa_e = (size_t)p_addr + size - 1;
- pa_s >>= ARCH_PAGE_SHIFT;
- pa_e >>= ARCH_PAGE_SHIFT;
- pages = pa_e - pa_s + 1;
- if (v_addr)
+ if (!aspace->page_table)
{
- vaddr = (size_t)v_addr;
- pa_s = (size_t)p_addr;
- if ((vaddr & ARCH_PAGE_MASK) != (pa_s & ARCH_PAGE_MASK))
- {
- return 0;
- }
- vaddr &= ~ARCH_PAGE_MASK;
- if (check_vaddr(mmu_info, (void*)vaddr, pages) != 0)
- {
- return 0;
- }
+ return;
}
- else
+
+ while (npages--)
{
- vaddr = find_vaddr(mmu_info, pages);
- }
- if (vaddr) {
rt_enter_critical();
- ret = __rt_hw_mmu_map(mmu_info, (void*)vaddr, p_addr, pages, attr);
- if (ret == 0)
- {
- rt_hw_cpu_tlb_invalidate();
- rt_exit_critical();
- return (void*)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK));
- }
+ _kenrel_unmap_4K(aspace->page_table, v_addr);
rt_exit_critical();
+
+ v_addr += ARCH_PAGE_SIZE;
}
- return 0;
}
-static int __rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void* v_addr, size_t npages, size_t attr)
+void rt_hw_aspace_switch(rt_aspace_t aspace)
{
- size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK;
- size_t loop_pa;
- size_t l1_off, l2_off;
- size_t *mmu_l1, *mmu_l2;
-
- if (!mmu_info)
+ if (aspace != &rt_kernel_space)
{
- return -1;
- }
-
- while (npages--)
- {
- loop_pa = (size_t)rt_pages_alloc(0);
- if (!loop_pa)
- goto err;
-
- l1_off = (loop_va >> ARCH_SECTION_SHIFT);
- l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
- mmu_l1 = (size_t*)mmu_info->vtable + l1_off;
+ void *pgtbl = aspace->page_table;
+ pgtbl = _rt_kmem_v2p(pgtbl);
- if (*mmu_l1 & ARCH_MMU_USED_MASK)
- {
- mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
- rt_page_ref_inc(mmu_l2, 0);
- }
- else
- {
- //mmu_l2 = (size_t*)rt_malloc_align(ARCH_PAGE_TBL_SIZE * 2, ARCH_PAGE_TBL_SIZE);
- mmu_l2 = (size_t*)rt_pages_alloc(0);
- if (mmu_l2)
- {
- rt_memset(mmu_l2, 0, ARCH_PAGE_TBL_SIZE * 2);
- /* cache maintain */
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l2, ARCH_PAGE_TBL_SIZE);
-
- *mmu_l1 = (((size_t)mmu_l2 + mmu_info->pv_off) | 0x1);
- /* cache maintain */
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l1, 4);
- }
- else
- goto err;
- }
-
- loop_pa += mmu_info->pv_off;
- *(mmu_l2 + l2_off) = (loop_pa | attr);
- /* cache maintain */
- rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l2 + l2_off, 4);
-
- loop_va += ARCH_PAGE_SIZE;
- }
- return 0;
-err:
- {
- /* error, unmap and quit */
- int i;
- void *va, *pa;
-
- va = (void*)((size_t)v_addr & ~ARCH_PAGE_MASK);
- for (i = 0; i < npages; i++)
- {
- pa = rt_hw_mmu_v2p(mmu_info, va);
- pa = (void*)((char*)pa - mmu_info->pv_off);
- rt_pages_free(pa, 0);
- va = (void*)((char*)va + ARCH_PAGE_SIZE);
- }
+ rt_hw_mmu_switch(pgtbl);
- __rt_hw_mmu_unmap(mmu_info, v_addr, npages);
- return -1;
+ rt_hw_tlb_invalidate_all_local();
}
}
-void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr)
+void init_mm_setup(unsigned int *mtbl, unsigned int size, unsigned int pv_off)
{
- size_t vaddr;
- size_t offset;
- int pages;
- int ret;
+ unsigned int va;
- if (!size)
+ for (va = 0; va < 0x1000; va++)
{
- return 0;
- }
+ unsigned int vaddr = (va << 20);
- offset = (size_t)v_addr & ARCH_PAGE_MASK;
- size += (offset + ARCH_PAGE_SIZE - 1);
- pages = (size >> ARCH_PAGE_SHIFT);
- if (v_addr)
- {
- vaddr = (size_t)v_addr;
- vaddr &= ~ARCH_PAGE_MASK;
- if (check_vaddr(mmu_info, (void*)vaddr, pages) != 0)
+ if (vaddr >= KERNEL_VADDR_START && vaddr - KERNEL_VADDR_START < size)
{
- return 0;
+ mtbl[va] = ((va << 20) + pv_off) | NORMAL_MEM;
}
- }
- else
- {
- vaddr = find_vaddr(mmu_info, pages);
- }
-
- if (vaddr)
- {
- rt_enter_critical();
- ret = __rt_hw_mmu_map_auto(mmu_info, (void*)vaddr, pages, attr);
- if (ret == 0)
+ else if (vaddr >= (KERNEL_VADDR_START + pv_off) && vaddr - (KERNEL_VADDR_START + pv_off) < size)
{
- rt_hw_cpu_tlb_invalidate();
- rt_exit_critical();
- return (void*)((char*)vaddr + offset);
+ mtbl[va] = (va << 20) | NORMAL_MEM;
+ }
+ else
+ {
+ mtbl[va] = 0;
}
- rt_exit_critical();
}
- return 0;
}
-void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size)
-{
- size_t va_s, va_e;
- int pages;
-
- va_s = (size_t)v_addr;
- va_e = (size_t)v_addr + size - 1;
- va_s >>= ARCH_PAGE_SHIFT;
- va_e >>= ARCH_PAGE_SHIFT;
- pages = va_e - va_s + 1;
- rt_enter_critical();
- __rt_hw_mmu_unmap(mmu_info, v_addr, pages);
- rt_hw_cpu_tlb_invalidate();
- rt_exit_critical();
-}
-
-void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr)
-{
- void *ret;
-
- rt_mm_lock();
- ret = _rt_hw_mmu_map(mmu_info, v_addr, p_addr, size, attr);
- rt_mm_unlock();
- return ret;
-}
-
-void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr)
-{
- void *ret;
-
- rt_mm_lock();
- ret = _rt_hw_mmu_map_auto(mmu_info, v_addr, size, attr);
- rt_mm_unlock();
- return ret;
-}
-
-void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size)
-{
- rt_mm_lock();
- _rt_hw_mmu_unmap(mmu_info, v_addr, size);
- rt_mm_unlock();
-}
-
-void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr)
+void *rt_hw_mmu_v2p(rt_aspace_t aspace, void* v_addr)
{
size_t l1_off, l2_off;
size_t *mmu_l1, *mmu_l2;
@@ -752,12 +376,9 @@ void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr)
l1_off = (size_t)v_addr >> ARCH_SECTION_SHIFT;
- if (!mmu_info)
- {
- return (void*)0;
- }
+ RT_ASSERT(aspace);
- mmu_l1 = (size_t*)mmu_info->vtable + l1_off;
+ mmu_l1 = (size_t*)aspace->page_table + l1_off;
tmp = *mmu_l1;
@@ -766,7 +387,7 @@ void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr)
case 0: /* not used */
break;
case 1: /* page table */
- mmu_l2 = (size_t *)((tmp & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
+ mmu_l2 = (size_t *)((tmp & ~ARCH_PAGE_TBL_MASK) - PV_OFFSET);
l2_off = (((size_t)v_addr & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
pa = *(mmu_l2 + l2_off);
if (pa & ARCH_MMU_USED_MASK)
@@ -793,39 +414,11 @@ void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr)
pa += ((size_t)v_addr & ARCH_SECTION_MASK);
return (void*)pa;
}
- return (void*)0;
+ return ARCH_MAP_FAILED;
}
-void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr)
+int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size,
+ enum rt_mmu_cntl cmd)
{
- void *ret;
-
- rt_mm_lock();
- ret = _rt_hw_mmu_v2p(mmu_info, v_addr);
- rt_mm_unlock();
- return ret;
+ return -RT_ENOSYS;
}
-
-void init_mm_setup(unsigned int *mtbl, unsigned int size, unsigned int pv_off)
-{
- unsigned int va;
-
- for (va = 0; va < 0x1000; va++)
- {
- unsigned int vaddr = (va << 20);
-
- if (vaddr >= KERNEL_VADDR_START && vaddr - KERNEL_VADDR_START < size)
- {
- mtbl[va] = ((va << 20) + pv_off) | NORMAL_MEM;
- }
- else if (vaddr >= (KERNEL_VADDR_START + pv_off) && vaddr - (KERNEL_VADDR_START + pv_off) < size)
- {
- mtbl[va] = (va << 20) | NORMAL_MEM;
- }
- else
- {
- mtbl[va] = 0;
- }
- }
-}
-#endif
diff --git a/libcpu/arm/cortex-a/mmu.h b/libcpu/arm/cortex-a/mmu.h
index 923d10df4b..04b4f485b0 100644
--- a/libcpu/arm/cortex-a/mmu.h
+++ b/libcpu/arm/cortex-a/mmu.h
@@ -11,6 +11,7 @@
#define __MMU_H_
#include <rtthread.h>
+#include <mm_aspace.h>
#define DESC_SEC (0x2)
#define MEMWBWA ((1<<12)|(3<<2)) /* write back, write allocate */
@@ -87,27 +88,43 @@ struct mem_desc
#define ARCH_TYPE_SUPERSECTION (1 << 18)
#define ARCH_ADDRESS_WIDTH_BITS 32
+#define ARCH_VADDR_WIDTH 32
-typedef struct
-{
- size_t *vtable;
- size_t vstart;
- size_t vend;
- size_t pv_off;
-} rt_mmu_info;
+/**
+ * *info it's possible to map (-1ul & ~ARCH_PAGE_MASK) but a not aligned -1 is
+ * never returned on a successful mapping
+ */
+#define ARCH_MAP_FAILED ((void *)-1)
-int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size_t *vtable, size_t pv_off);
-int rt_hw_mmu_ioremap_init(rt_mmu_info *mmu_info, void* v_address, size_t size);
+int rt_hw_mmu_ioremap_init(struct rt_aspace *aspace, void *v_address, size_t size);
void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_uint32_t size);
-#ifdef RT_USING_SMART
-void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr);
-void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr);
-#else
-void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr);
-#endif
+void rt_hw_mmu_setup(struct rt_aspace *aspace, struct mem_desc *mdesc, int desc_nr);
+
+int rt_hw_mmu_map_init(struct rt_aspace *aspace, void *v_address, size_t size, size_t *vtable, size_t pv_off);
+void *rt_hw_mmu_map(struct rt_aspace *aspace, void *v_addr, void *p_addr, size_t size, size_t attr);
+void rt_hw_mmu_unmap(struct rt_aspace *aspace, void *v_addr, size_t size);
+
+void rt_hw_aspace_switch(struct rt_aspace *aspace);
+void rt_hw_mmu_switch(void *tbl);
+
+void *rt_hw_mmu_v2p(struct rt_aspace *aspace, void *vaddr);
+void rt_hw_mmu_kernel_map_init(struct rt_aspace *aspace, size_t vaddr_start, size_t size);
+void *rt_hw_mmu_tbl_get();
+
+static inline void *_rt_kmem_v2p(void *vaddr)
+{
+ return rt_hw_mmu_v2p(&rt_kernel_space, vaddr);
+}
+
+static inline void *rt_kmem_v2p(void *vaddr)
+{
+ MM_PGTBL_LOCK(&rt_kernel_space);
+ void *paddr = _rt_kmem_v2p(vaddr);
+ MM_PGTBL_UNLOCK(&rt_kernel_space);
+ return paddr;
+}
-void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size);
-void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr);
+int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size, enum rt_mmu_cntl cmd);
#endif
diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S
index 865f005dc8..94f96468fa 100644
--- a/libcpu/arm/cortex-a/start_gcc.S
+++ b/libcpu/arm/cortex-a/start_gcc.S
@@ -258,34 +258,27 @@ rt_hw_set_process_id:
MCR p15, 0, r0, c13, c0, 1
mov pc, lr
+#endif
.global rt_hw_mmu_switch
rt_hw_mmu_switch:
- mov r3, #0
- mcr p15, 0, r3, c13, c0, 1 /* set contextid = 0, for synchronization*/
- isb
-
orr r0, #0x18
- mcr p15, 0, r0, c2, c0, 0 /* ttbr0 */
-
- isb
- mov r1, r1, LSL #0x8
- and r2, r2, #0xff
- orr r1, r1, r2 /* contextid.PROCID = pid, contextid.ASID = asid*/
- mcr p15, 0, r1, c13, c0, 1 /* set contextid = r1*/
- isb
+ mcr p15, 0, r0, c2, c0, 0 // ttbr0
- mcr p15, 0, r0, c7, c5, 0 /* iciallu */
- mcr p15, 0, r0, c7, c5, 6 /* bpiall */
+ //invalid tlb
+ mov r0, #0
+ mcr p15, 0, r0, c8, c7, 0
+ mcr p15, 0, r0, c7, c5, 0 //iciallu
+ mcr p15, 0, r0, c7, c5, 6 //bpiall
dsb
isb
mov pc, lr
+
.global rt_hw_mmu_tbl_get
rt_hw_mmu_tbl_get:
mrc p15, 0, r0, c2, c0, 0 /* ttbr0 */
bic r0, #0x18
mov pc, lr
-#endif
_halt:
wfe
@@ -459,7 +452,7 @@ rt_hw_context_switch_interrupt_do:
bl rt_thread_self
#ifdef RT_USING_SMART
mov r4, r0
- bl lwp_mmu_switch
+ bl lwp_aspace_switch
mov r0, r4
bl lwp_user_setting_restore
#endif
diff --git a/libcpu/arm/cortex-a/tlb.h b/libcpu/arm/cortex-a/tlb.h
new file mode 100644
index 0000000000..1dfb741163
--- /dev/null
+++ b/libcpu/arm/cortex-a/tlb.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-12-12 WangXiaoyao the first version
+ */
+#ifndef __TLB_H__
+#define __TLB_H__
+
+#include "mm_aspace.h"
+#include <rtthread.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#define dsb(scope) __asm__ volatile("dsb " #scope : : : "memory")
+#define isb() __asm__ volatile("isb" : : : "memory")
+#define STORE_CP32(r, name...) "mcr " RT_STRINGIFY(CP32(%r, name)) ";"
+
+#define WRITE_CP32(v, name...) do { \
+ register uint32_t _r = (v); \
+ asm volatile(STORE_CP32(0, name) : : "r" (_r)); \
+} while (0)
+
+static inline void rt_hw_tlb_invalidate_all(void)
+{
+ asm volatile ("mcr p15, 0, r0, c8, c7, 0\ndsb\nisb" ::: "memory");
+}
+
+static inline void rt_hw_tlb_invalidate_all_local(void)
+{
+ rt_hw_tlb_invalidate_all();
+}
+
+static inline void rt_hw_tlb_invalidate_aspace(rt_aspace_t aspace)
+{
+ rt_hw_tlb_invalidate_all();
+}
+
+static inline void rt_hw_tlb_invalidate_range(rt_aspace_t aspace, void *start,
+ size_t size, size_t stride)
+{
+ rt_hw_tlb_invalidate_all();
+}
+
+#endif /* __TLB_H__ */
diff --git a/libcpu/arm/cortex-a/trap.c b/libcpu/arm/cortex-a/trap.c
index 79897cd39c..425e51b9d0 100644
--- a/libcpu/arm/cortex-a/trap.c
+++ b/libcpu/arm/cortex-a/trap.c
@@ -8,12 +8,13 @@
* 2013-07-20 Bernard first version
*/
-#include <rtthread.h>
-#include <rthw.h>
-#include <board.h>
#include <backtrace.h>
+#include <board.h>
+#include <rthw.h>
+#include <rtthread.h>
#include "interrupt.h"
+#include "mm_fault.h"
#ifdef RT_USING_FINSH
extern long list_thread(void);
@@ -44,14 +45,23 @@ void check_user_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *info)
int check_user_stack(struct rt_hw_exp_stack *regs)
{
- void* dfar = RT_NULL;
+ void *dfar = RT_NULL;
+ asm volatile("MRC p15, 0, %0, c6, c0, 0" : "=r"(dfar));
- asm volatile ("MRC p15, 0, %0, c6, c0, 0":"=r"(dfar));
- if (arch_expand_user_stack(dfar))
+ if ((dfar >= (void *)USER_STACK_VSTART) && (dfar < (void *)USER_STACK_VEND))
{
- regs->pc -= 8;
- return 1;
+ struct rt_mm_fault_msg msg = {
+ .fault_op = MM_FAULT_OP_WRITE,
+ .fault_type = MM_FAULT_TYPE_PAGE_FAULT,
+ .vaddr = dfar,
+ };
+ if (rt_mm_fault_try_fix(&msg))
+ {
+ regs->pc -= 8;
+ return 1;
+ }
}
+
return 0;
}
#endif
@@ -79,7 +89,7 @@ void rt_hw_show_register(struct rt_hw_exp_stack *regs)
rt_kprintf("ttbr0:0x%08x\n", v);
asm volatile ("MRC p15, 0, %0, c6, c0, 0":"=r"(v));
rt_kprintf("dfar:0x%08x\n", v);
- rt_kprintf("0x%08x -> 0x%08x\n", v, rt_hw_mmu_v2p(&mmu_info, (void *)v));
+ rt_kprintf("0x%08x -> 0x%08x\n", v, rt_kmem_v2p((void *)v));
}
#endif
}
diff --git a/libcpu/risc-v/t-head/c906/backtrace.c b/libcpu/risc-v/t-head/c906/backtrace.c
new file mode 100644
index 0000000000..ad5dd7d2d3
--- /dev/null
+++ b/libcpu/risc-v/t-head/c906/backtrace.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ */
+
+#include <rtthread.h>
+#ifdef RT_USING_SMART
+#include <lwp_arch.h>
+
+#define TRANCE_LEVEL 20
+
+extern rt_ubase_t __text_start[];
+extern rt_ubase_t __text_end[];
+
+static char *_get_elf_name(size_t sepc);
+
+void rt_hw_backtrace(rt_uint32_t *ffp, rt_ubase_t sepc)
+{
+ rt_ubase_t *ra;
+ rt_ubase_t *fp;
+ rt_ubase_t vas, vae;
+ int i, j;
+
+ rt_kprintf("riscv64-unknown-linux-musl-addr2line -e %s -a -f", _get_elf_name(sepc));
+
+ fp = (rt_ubase_t *)ffp;
+
+ if (!fp)
+ {
+ asm volatile("mv %0, s0"
+ : "=r"(fp));
+ }
+
+ if (sepc)
+ {
+ rt_kprintf(" %p", sepc - 0x4);
+ }
+
+ if (fp > (rt_ubase_t *)USER_VADDR_START && fp < (rt_ubase_t *)USER_VADDR_TOP)
+ {
+ vas = USER_VADDR_START;
+ vae = USER_VADDR_TOP;
+ }
+ else
+ {
+ vas = (rt_ubase_t)&__text_start;
+ vae = (rt_ubase_t)&__text_end;
+ }
+
+ for (i = j = 0; i < TRANCE_LEVEL; i++)
+ {
+ if (RT_ALIGN((rt_ubase_t)fp, sizeof(void *)) != (rt_ubase_t)fp)
+ {
+ break;
+ }
+
+ ra = fp - 1;
+ if (!_rt_kmem_v2p(ra) || *ra < vas || *ra > vae)
+ break;
+
+ rt_kprintf(" %p", *ra - 0x04);
+
+ fp = fp - 2;
+ if (!_rt_kmem_v2p(fp))
+ break;
+ fp = (rt_ubase_t *)(*fp);
+ if (!fp)
+ break;
+ }
+
+ rt_kputs("\r\n");
+}
+
+static void _assert_backtrace_cb(const char *ex, const char *func, rt_size_t line)
+{
+ rt_hw_interrupt_disable();
+ rt_kprintf("(%s) assertion failed at function:%s, line number:%d \n", ex, func, line);
+
+ rt_hw_backtrace(0, 0);
+ rt_hw_cpu_shutdown();
+}
+
+static int rt_hw_backtrace_init(void)
+{
+ rt_assert_set_hook(_assert_backtrace_cb);
+
+ return 0;
+}
+INIT_BOARD_EXPORT(rt_hw_backtrace_init);
+
+static void backtrace_test(int args, char *argv[])
+{
+ int *p = (void *)-1;
+ init_fn_t ft = 0;
+
+ if (args < 2)
+ {
+ rt_kprintf("backtrace_test usage:backtrace_test a(assert)/m(invalid memory)/i(illegal instruction)\r\n");
+ return;
+ }
+
+ if (!rt_strcmp(argv[1], "a"))
+ {
+ rt_kprintf("Assert test:\r\n", argv[1]);
+ RT_ASSERT(0);
+ }
+ else if (!rt_strcmp(argv[1], "m"))
+ {
+ rt_kprintf("Access invalid memory:\r\n", argv[1]);
+ *p = 0;
+ }
+ else if (!rt_strcmp(argv[1], "i"))
+ {
+ rt_kprintf("Illegal instruction:\r\n", argv[1]);
+ ft();
+ }
+ else
+ {
+ rt_kprintf("Unknown cmd :%s.\r\n", argv[1]);
+ }
+}
+MSH_CMD_EXPORT(backtrace_test, backtrace test case);
+
+extern struct rt_thread *rt_current_thread;
+
+#define IN_USERSPACE (sepc > USER_VADDR_START && sepc < USER_VADDR_TOP)
+
+static char *_get_elf_name(size_t sepc)
+{
+ return IN_USERSPACE ? rt_current_thread->name : "rtthread.elf";
+}
+
+#endif /* RT_USING_SMART */
diff --git a/libcpu/risc-v/t-head/c906/context_gcc.S b/libcpu/risc-v/t-head/c906/context_gcc.S
index 1442e2bf0a..595cd8f3d7 100644
--- a/libcpu/risc-v/t-head/c906/context_gcc.S
+++ b/libcpu/risc-v/t-head/c906/context_gcc.S
@@ -23,7 +23,7 @@ rt_hw_context_switch_to:
#ifdef RT_USING_SMART
mv a0, s1
- jal lwp_mmu_switch
+ jal lwp_aspace_switch
#endif
RESTORE_ALL
@@ -56,7 +56,7 @@ rt_hw_context_switch:
#ifdef RT_USING_SMART
mv a0, s1
- jal lwp_mmu_switch
+ jal lwp_aspace_switch
#endif
RESTORE_ALL
diff --git a/libcpu/risc-v/t-head/c906/cpuport.c b/libcpu/risc-v/t-head/c906/cpuport.c
index 592f66bfb2..847d0b7671 100644
--- a/libcpu/risc-v/t-head/c906/cpuport.c
+++ b/libcpu/risc-v/t-head/c906/cpuport.c
@@ -14,6 +14,7 @@
#include <rtthread.h>
#include "cpuport.h"
+#include "sbi.h"
#include "stack.h"
#include <lwp_arch.h>
@@ -110,10 +111,8 @@ void rt_hw_cpu_shutdown()
rt_kprintf("shutdown...\n");
level = rt_hw_interrupt_disable();
- while (level)
- {
- RT_ASSERT(0);
- }
+ sbi_shutdown();
+ while (1);
}
int rt_hw_cpu_id(void)
diff --git a/libcpu/risc-v/t-head/c906/cpuport.h b/libcpu/risc-v/t-head/c906/cpuport.h
index ceea4ef5af..640c5281cf 100644
--- a/libcpu/risc-v/t-head/c906/cpuport.h
+++ b/libcpu/risc-v/t-head/c906/cpuport.h
@@ -37,19 +37,21 @@
#define CTX_REG_NR (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR)
#ifndef __ASSEMBLY__
+#include <rtthread.h>
+
rt_inline void rt_hw_dsb()
{
- asm volatile("fence":::"memory");
+ __asm__ volatile("fence":::"memory");
}
rt_inline void rt_hw_dmb()
{
- asm volatile("fence":::"memory");
+ __asm__ volatile("fence":::"memory");
}
rt_inline void rt_hw_isb()
{
- asm volatile(OPC_FENCE_I:::"memory");
+ __asm__ volatile(OPC_FENCE_I:::"memory");
}
int rt_hw_cpu_id(void);
diff --git a/libcpu/risc-v/t-head/c906/encoding.h b/libcpu/risc-v/t-head/c906/encoding.h
index 7197e6b84b..25f1b771db 100644
--- a/libcpu/risc-v/t-head/c906/encoding.h
+++ b/libcpu/risc-v/t-head/c906/encoding.h
@@ -33,7 +33,7 @@
#define SSTATUS_FS_CLEAN 0x00004000
#define SSTATUS_FS_DIRTY 0x00006000
#define SSTATUS_XS 0x00018000
-#define SSTATUS_PUM 0x00040000
+#define SSTATUS_SUM 0x00040000
#define SSTATUS32_SD 0x80000000
#define SSTATUS64_SD 0x8000000000000000
diff --git a/libcpu/risc-v/t-head/c906/interrupt_gcc.S b/libcpu/risc-v/t-head/c906/interrupt_gcc.S
index 084dfa25f4..c9659eb512 100644
--- a/libcpu/risc-v/t-head/c906/interrupt_gcc.S
+++ b/libcpu/risc-v/t-head/c906/interrupt_gcc.S
@@ -96,7 +96,7 @@ copy_context_loop_interrupt:
#ifdef RT_USING_SMART
mv a0, s1
jal rt_thread_sp_to_thread
- jal lwp_mmu_switch
+ jal lwp_aspace_switch
#endif
spurious_interrupt:
diff --git a/libcpu/risc-v/t-head/c906/mmu.c b/libcpu/risc-v/t-head/c906/mmu.c
index 0d461bc861..0093f5e836 100644
--- a/libcpu/risc-v/t-head/c906/mmu.c
+++ b/libcpu/risc-v/t-head/c906/mmu.c
@@ -8,628 +8,498 @@
* 2021-01-30 lizhirui first version
*/
+#include "rtconfig.h"
#include <rtthread.h>
-#include <rthw.h>
-#include <board.h>
-#include "page.h"
-#include <stdlib.h>
-#include <string.h>
+#include <stddef.h>
+#include <stdint.h>
+
#include <cache.h>
+#include <mm_aspace.h>
+#include <mm_page.h>
+#include <mmu.h>
+#include <riscv_mmu.h>
+#include <tlb.h>
+
+#ifdef RT_USING_SMART
+#include <ioremap.h>
+#include <lwp_user_mm.h>
+#include <tlb.h>
+#endif
-#include "riscv.h"
-#include "riscv_mmu.h"
-#include "mmu.h"
+#define DBG_TAG "MMU"
+#define DBG_LVL DBG_LOG
+#include <rtdbg.h>
-void *current_mmu_table = RT_NULL;
+#ifndef RT_USING_SMART
+#define PV_OFFSET 0
+#define USER_VADDR_START 0
+#endif
-static void rt_hw_cpu_tlb_invalidate()
+static size_t _unmap_area(struct rt_aspace *aspace, void *v_addr, size_t size);
+
+void rt_hw_aspace_switch(rt_aspace_t aspace)
{
- rt_size_t satpv = read_csr(satp);
- write_csr(satp,satpv);
- mmu_flush_tlb();
+ uintptr_t page_table = (uintptr_t)_rt_kmem_v2p(aspace->page_table);
+
+ write_csr(satp, (((size_t)SATP_MODE) << SATP_MODE_OFFSET) |
+ ((rt_ubase_t)page_table >> PAGE_OFFSET_BIT));
+ rt_hw_tlb_invalidate_all_local();
}
+static void *current_mmu_table = RT_NULL;
+
+volatile __attribute__((aligned(4 * 1024)))
+rt_ubase_t MMUTable[__SIZE(VPN2_BIT)];
+
void *rt_hw_mmu_tbl_get()
{
return current_mmu_table;
}
-void rt_hw_mmu_switch(void *mmu_table)
+static int _map_one_page(struct rt_aspace *aspace, void *va, void *pa,
+ size_t attr)
{
- current_mmu_table = mmu_table;
- RT_ASSERT(__CHECKALIGN(mmu_table,PAGE_OFFSET_BIT));
- mmu_set_pagetable((rt_ubase_t)mmu_table);
- rt_hw_cpu_dcache_clean_all();
- rt_hw_cpu_icache_invalidate_all();
-}
+ rt_size_t l1_off, l2_off, l3_off;
+ rt_size_t *mmu_l1, *mmu_l2, *mmu_l3;
-int rt_hw_mmu_map_init(rt_mmu_info *mmu_info,void *v_address,rt_size_t size,rt_size_t *vtable,rt_size_t pv_off)
-{
- size_t l1_off,va_s,va_e;
- rt_base_t level;
+ l1_off = GET_L1((size_t)va);
+ l2_off = GET_L2((size_t)va);
+ l3_off = GET_L3((size_t)va);
- if((!mmu_info) || (!vtable))
- {
- return -1;
- }
+ mmu_l1 = ((rt_size_t *)aspace->page_table) + l1_off;
- va_s = (rt_size_t)v_address;
- va_e = ((rt_size_t)v_address) + size - 1;
-
- if(va_e < va_s)
+ if (PTE_USED(*mmu_l1))
{
- return -1;
+ mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1), PV_OFFSET);
}
-
- //convert address to level 1 page frame id
- va_s = GET_L1(va_s);
- va_e = GET_L1(va_e);
-
- if(va_s == 0)
- {
- return -1;
- }
-
- level = rt_hw_interrupt_disable();
-
- //vtable initialization check
- for(l1_off = va_s;l1_off <= va_e;l1_off++)
+ else
{
- size_t v = vtable[l1_off];
+ mmu_l2 = (rt_size_t *)rt_pages_alloc(0);
- if(v)
+ if (mmu_l2)
{
- rt_hw_interrupt_enable(level);
- return 0;
+ rt_memset(mmu_l2, 0, PAGE_SIZE);
+ rt_hw_cpu_dcache_clean(mmu_l2, PAGE_SIZE);
+ *mmu_l1 = COMBINEPTE((rt_size_t)VPN_TO_PPN(mmu_l2, PV_OFFSET),
+ PAGE_DEFAULT_ATTR_NEXT);
+ rt_hw_cpu_dcache_clean(mmu_l1, sizeof(*mmu_l1));
+ }
+ else
+ {
+ return -1;
}
}
- mmu_info -> vtable = vtable;
- mmu_info -> vstart = va_s;
- mmu_info -> vend = va_e;
- mmu_info -> pv_off = pv_off;
-
- rt_hw_interrupt_enable(level);
- return 0;
-}
-
-void rt_hw_mmu_kernel_map_init(rt_mmu_info *mmu_info,rt_size_t vaddr_start,rt_size_t size)
-{
- rt_size_t paddr_start = __UMASKVALUE(VPN_TO_PPN(vaddr_start,mmu_info -> pv_off),PAGE_OFFSET_MASK);
- rt_size_t va_s = GET_L1(vaddr_start);
- rt_size_t va_e = GET_L1(vaddr_start + size - 1);
- rt_size_t i;
-
- for(i = va_s;i <= va_e;i++)
- {
- mmu_info -> vtable[i] = COMBINEPTE(paddr_start,PAGE_ATTR_RWX | PTE_G | PTE_V | PTE_CACHE | PTE_SHARE | PTE_BUF | PTE_A | PTE_D);
- paddr_start += L1_PAGE_SIZE;
- }
-
- rt_hw_cpu_tlb_invalidate();
-}
-
-//find a range of free virtual address specified by pages
-static rt_size_t find_vaddr(rt_mmu_info *mmu_info,rt_size_t pages)
-{
- rt_size_t l1_off,l2_off,l3_off;
- rt_size_t *mmu_l1,*mmu_l2,*mmu_l3;
- rt_size_t find_l1 = 0,find_l2 = 0,find_l3 = 0;
- rt_size_t n = 0;
-
- if(!pages)
- {
- return 0;
- }
-
- if(!mmu_info)
+ if (PTE_USED(*(mmu_l2 + l2_off)))
{
- return 0;
+ RT_ASSERT(!PAGE_IS_LEAF(*(mmu_l2 + l2_off)));
+ mmu_l3 =
+ (rt_size_t *)PPN_TO_VPN(GET_PADDR(*(mmu_l2 + l2_off)), PV_OFFSET);
}
-
- for(l1_off = mmu_info -> vstart;l1_off <= mmu_info -> vend;l1_off++)
+ else
{
- mmu_l1 = ((rt_size_t *)mmu_info -> vtable) + l1_off;
+ mmu_l3 = (rt_size_t *)rt_pages_alloc(0);
- if(PTE_USED(*mmu_l1))
+ if (mmu_l3)
{
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l1));
- mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1),mmu_info -> pv_off);
-
- for(l2_off = 0;l2_off < __SIZE(VPN1_BIT);l2_off++)
- {
- if(PTE_USED(*(mmu_l2 + l2_off)))
- {
- RT_ASSERT(!PAGE_IS_LEAF(*(mmu_l2 + l2_off)));
- mmu_l3 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*(mmu_l2 + l2_off)),mmu_info -> pv_off);
-
- for(l3_off = 0;l3_off < __SIZE(VPN0_BIT);l3_off++)
- {
- if(PTE_USED(*(mmu_l3 + l3_off)))
- {
- RT_ASSERT(PAGE_IS_LEAF(*(mmu_l3 + l3_off)));
- n = 0;//in use
- }
- else
- {
- if(!n)
- {
- find_l1 = l1_off;
- find_l2 = l2_off;
- find_l3 = l3_off;
- }
-
- n++;
-
- if(n >= pages)
- {
- return COMBINEVADDR(find_l1,find_l2,find_l3);
- }
- }
- }
- }
- else
- {
- if(!n)
- {
- find_l1 = l1_off;
- find_l2 = l2_off;
- find_l3 = 0;
- }
-
- n += __SIZE(VPN0_BIT);
-
- if(n >= pages)
- {
- return COMBINEVADDR(find_l1,find_l2,find_l3);
- }
- }
- }
+ rt_memset(mmu_l3, 0, PAGE_SIZE);
+ rt_hw_cpu_dcache_clean(mmu_l3, PAGE_SIZE);
+ *(mmu_l2 + l2_off) =
+ COMBINEPTE((rt_size_t)VPN_TO_PPN(mmu_l3, PV_OFFSET),
+ PAGE_DEFAULT_ATTR_NEXT);
+ rt_hw_cpu_dcache_clean(mmu_l2, sizeof(*mmu_l2));
+ // declares a reference to parent page table
+ rt_page_ref_inc((void *)mmu_l2, 0);
}
else
{
- if(!n)
- {
- find_l1 = l1_off;
- find_l2 = 0;
- find_l3 = 0;
- }
-
- n += __SIZE(VPN1_BIT);
-
- if(n >= pages)
- {
- return COMBINEVADDR(find_l1,find_l2,find_l3);
- }
+ return -1;
}
}
+ RT_ASSERT(!PTE_USED(*(mmu_l3 + l3_off)));
+ // declares a reference to parent page table
+ rt_page_ref_inc((void *)mmu_l3, 0);
+ *(mmu_l3 + l3_off) = COMBINEPTE((rt_size_t)pa, attr);
+ rt_hw_cpu_dcache_clean(mmu_l3 + l3_off, sizeof(*(mmu_l3 + l3_off)));
return 0;
}
-//check whether the range of virtual address are free
-static int check_vaddr(rt_mmu_info *mmu_info,void *va,rt_size_t pages)
+/** rt_hw_mmu_map will never override existed page table entry */
+void *rt_hw_mmu_map(struct rt_aspace *aspace, void *v_addr, void *p_addr,
+ size_t size, size_t attr)
{
- rt_size_t loop_va = __UMASKVALUE((rt_size_t)va,PAGE_OFFSET_MASK);
- rt_size_t l1_off,l2_off,l3_off;
- rt_size_t *mmu_l1,*mmu_l2,*mmu_l3;
+ int ret = -1;
+ void *unmap_va = v_addr;
+ size_t npages = size >> ARCH_PAGE_SHIFT;
- if(!pages)
+ // TODO trying with HUGEPAGE here
+ while (npages--)
{
- return -1;
- }
-
- if(!mmu_info)
- {
- return -1;
- }
-
- while(pages--)
- {
- l1_off = GET_L1(loop_va);
- l2_off = GET_L2(loop_va);
- l3_off = GET_L3(loop_va);
- mmu_l1 = ((rt_size_t *)mmu_info -> vtable) + l1_off;
-
- if(PTE_USED(*mmu_l1))
+ ret = _map_one_page(aspace, v_addr, p_addr, attr);
+ if (ret != 0)
{
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l1));
- mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1),mmu_info -> pv_off) + l2_off;
-
- if(PTE_USED(*mmu_l2))
+ /* error, undo map */
+ while (unmap_va != v_addr)
{
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l2));
- mmu_l3 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l2),mmu_info -> pv_off) + l3_off;
-
- if(PTE_USED(*mmu_l3))
- {
- RT_ASSERT(PAGE_IS_LEAF(*mmu_l3));
- return -1;
- }
+ MM_PGTBL_LOCK(aspace);
+ _unmap_area(aspace, unmap_va, ARCH_PAGE_SIZE);
+ MM_PGTBL_UNLOCK(aspace);
+ unmap_va += ARCH_PAGE_SIZE;
}
+ break;
}
+ v_addr += ARCH_PAGE_SIZE;
+ p_addr += ARCH_PAGE_SIZE;
+ }
- loop_va += PAGE_SIZE;
+ if (ret == 0)
+ {
+ return unmap_va;
}
- return 0;
+ return NULL;
}
-static void __rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t npages)
+static void _unmap_pte(rt_size_t *pentry, rt_size_t *lvl_entry[], int level)
{
- rt_size_t loop_va = __UMASKVALUE((rt_size_t)v_addr,PAGE_OFFSET_MASK);
- rt_size_t l1_off,l2_off,l3_off;
- rt_size_t *mmu_l1,*mmu_l2,*mmu_l3;
- rt_size_t *ref_cnt;
-
- RT_ASSERT(mmu_info);
-
- while(npages--)
+ int loop_flag = 1;
+ while (loop_flag)
{
- l1_off = (rt_size_t)GET_L1(loop_va);
- RT_ASSERT((l1_off >= mmu_info -> vstart) && (l1_off <= mmu_info -> vend));
- l2_off = (rt_size_t)GET_L2(loop_va);
- l3_off = (rt_size_t)GET_L3(loop_va);
- mmu_l1 = ((rt_size_t *)mmu_info -> vtable) + l1_off;
- RT_ASSERT(PTE_USED(*mmu_l1))
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l1));
- mmu_l2 = ((rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1),mmu_info -> pv_off)) + l2_off;
- RT_ASSERT(PTE_USED(*mmu_l2));
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l2));
- mmu_l3 = ((rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l2),mmu_info -> pv_off)) + l3_off;
- RT_ASSERT(PTE_USED(*mmu_l3));
- RT_ASSERT(PAGE_IS_LEAF(*(mmu_l3)));
- *mmu_l3 = 0;
- rt_hw_cpu_dcache_clean(mmu_l3,sizeof(*mmu_l3));
- mmu_l3 -= l3_off;
- ref_cnt = mmu_l3 + __SIZE(VPN0_BIT);
- (*ref_cnt)--;
+ loop_flag = 0;
+ *pentry = 0;
+ rt_hw_cpu_dcache_clean(pentry, sizeof(*pentry));
- if(!*ref_cnt)
+ // we don't handle level 0, which is maintained by caller
+ if (level > 0)
{
- //release level 3 page
- rt_pages_free(mmu_l3,1);//entry page and ref_cnt page
- *mmu_l2 = 0;
- rt_hw_cpu_dcache_clean(mmu_l2,sizeof(*mmu_l2));
- mmu_l2 -= l2_off;
+ void *page = (void *)((rt_ubase_t)pentry & ~ARCH_PAGE_MASK);
- ref_cnt = mmu_l2 + __SIZE(VPN1_BIT);
- (*ref_cnt)--;
+ // decrease reference from child page to parent
+ rt_pages_free(page, 0);
- if(!*ref_cnt)
+ int free = rt_page_ref_get(page, 0);
+ if (free == 1)
{
- //release level 2 page
- rt_pages_free(mmu_l2,1);//entry page and ref_cnt page
- *mmu_l1 = 0;
- rt_hw_cpu_dcache_clean(mmu_l1,sizeof(*mmu_l1));
+ rt_pages_free(page, 0);
+ pentry = lvl_entry[--level];
+ loop_flag = 1;
}
}
-
- loop_va += PAGE_SIZE;
}
}
-static int __rt_hw_mmu_map(rt_mmu_info *mmu_info,void *v_addr,void *p_addr,rt_size_t npages,rt_size_t attr)
+static size_t _unmap_area(struct rt_aspace *aspace, void *v_addr, size_t size)
{
- rt_size_t loop_va = __UMASKVALUE((rt_size_t)v_addr,PAGE_OFFSET_MASK);
- rt_size_t loop_pa = __UMASKVALUE((rt_size_t)p_addr,PAGE_OFFSET_MASK);
- rt_size_t l1_off,l2_off,l3_off;
- rt_size_t *mmu_l1,*mmu_l2,*mmu_l3;
- rt_size_t *ref_cnt;
- //rt_kprintf("v_addr = 0x%p,p_addr = 0x%p,npages = %lu\n",v_addr,p_addr,npages);
+ rt_size_t loop_va = __UMASKVALUE((rt_size_t)v_addr, PAGE_OFFSET_MASK);
+ size_t unmapped = 0;
+
+ int i = 0;
+ rt_size_t lvl_off[3];
+ rt_size_t *lvl_entry[3];
+ lvl_off[0] = (rt_size_t)GET_L1(loop_va);
+ lvl_off[1] = (rt_size_t)GET_L2(loop_va);
+ lvl_off[2] = (rt_size_t)GET_L3(loop_va);
+ unmapped = 1 << (ARCH_PAGE_SHIFT + ARCH_INDEX_WIDTH * 2ul);
+
+ rt_size_t *pentry;
+ lvl_entry[i] = ((rt_size_t *)aspace->page_table + lvl_off[i]);
+ pentry = lvl_entry[i];
- if(!mmu_info)
+ // find leaf page table entry
+ while (PTE_USED(*pentry) && !PAGE_IS_LEAF(*pentry))
{
- return -1;
+ i += 1;
+ lvl_entry[i] = ((rt_size_t *)PPN_TO_VPN(GET_PADDR(*pentry), PV_OFFSET) +
+ lvl_off[i]);
+ pentry = lvl_entry[i];
+ unmapped >>= ARCH_INDEX_WIDTH;
}
- while(npages--)
+ // clear PTE & setup its
+ if (PTE_USED(*pentry))
{
- l1_off = GET_L1(loop_va);
- l2_off = GET_L2(loop_va);
- l3_off = GET_L3(loop_va);
- mmu_l1 = ((rt_size_t *)mmu_info -> vtable) + l1_off;
-
- if(PTE_USED(*mmu_l1))
- {
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l1));
- mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1),mmu_info -> pv_off);
- }
- else
- {
- mmu_l2 = (rt_size_t *)rt_pages_alloc(1);
+ _unmap_pte(pentry, lvl_entry, i);
+ }
- if(mmu_l2)
- {
- rt_memset(mmu_l2,0,PAGE_SIZE * 2);
- rt_hw_cpu_dcache_clean(mmu_l2,PAGE_SIZE * 2);
- *mmu_l1 = COMBINEPTE((rt_size_t)VPN_TO_PPN(mmu_l2,mmu_info -> pv_off),PAGE_DEFAULT_ATTR_NEXT);
- rt_hw_cpu_dcache_clean(mmu_l1,sizeof(*mmu_l1));
- }
- else
- {
- __rt_hw_mmu_unmap(mmu_info,v_addr,npages);
- return -1;
- }
- }
+ return unmapped;
+}
- if(PTE_USED(*(mmu_l2 + l2_off)))
- {
- RT_ASSERT(!PAGE_IS_LEAF(*(mmu_l2 + l2_off)));
- mmu_l3 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*(mmu_l2 + l2_off)),mmu_info -> pv_off);
- }
- else
- {
- mmu_l3 = (rt_size_t *)rt_pages_alloc(1);
+/** unmap is different from map that it can handle multiple pages */
+void rt_hw_mmu_unmap(struct rt_aspace *aspace, void *v_addr, size_t size)
+{
+ // caller guarantee that v_addr & size are page aligned
+ if (!aspace->page_table)
+ {
+ return;
+ }
+ size_t unmapped = 0;
- if(mmu_l3)
- {
- rt_memset(mmu_l3,0,PAGE_SIZE * 2);
- rt_hw_cpu_dcache_clean(mmu_l3,PAGE_SIZE * 2);
- *(mmu_l2 + l2_off) = COMBINEPTE((rt_size_t)VPN_TO_PPN(mmu_l3,mmu_info -> pv_off),PAGE_DEFAULT_ATTR_NEXT);
- rt_hw_cpu_dcache_clean(mmu_l2,sizeof(*mmu_l2));
- ref_cnt = mmu_l2 + __SIZE(VPN1_BIT);
- (*ref_cnt)++;
- }
- else
- {
- __rt_hw_mmu_unmap(mmu_info,v_addr,npages);
- return -1;
- }
- }
+ while (size > 0)
+ {
+ MM_PGTBL_LOCK(aspace);
+ unmapped = _unmap_area(aspace, v_addr, size);
+ MM_PGTBL_UNLOCK(aspace);
- RT_ASSERT(!PTE_USED(*(mmu_l3 + l3_off)));
- ref_cnt = mmu_l3 + __SIZE(VPN0_BIT);
- (*ref_cnt)++;
- *(mmu_l3 + l3_off) = COMBINEPTE((rt_size_t)loop_pa,PAGE_DEFAULT_ATTR_LEAF);
- rt_hw_cpu_dcache_clean(mmu_l3 + l3_off,sizeof(*(mmu_l3 + l3_off)));
+ // when unmapped == 0, region not exist in pgtbl
+ if (!unmapped || unmapped > size)
+ break;
- loop_va += PAGE_SIZE;
- loop_pa += PAGE_SIZE;
+ size -= unmapped;
+ v_addr += unmapped;
}
+}
- return 0;
+#ifdef RT_USING_SMART
+static inline void _init_region(void *vaddr, size_t size)
+{
+ rt_ioremap_start = vaddr;
+ rt_ioremap_size = size;
+ rt_mpr_start = rt_ioremap_start - rt_mpr_size;
+ rt_kprintf("rt_ioremap_start: %p, rt_mpr_start: %p\n", rt_ioremap_start, rt_mpr_start);
+}
+#else
+static inline void _init_region(void *vaddr, size_t size)
+{
+ rt_mpr_start = vaddr - rt_mpr_size;
}
+#endif
-void *_rt_hw_mmu_map(rt_mmu_info *mmu_info,void *v_addr,void *p_addr,rt_size_t size,rt_size_t attr)
+int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, rt_size_t size,
+ rt_size_t *vtable, rt_size_t pv_off)
{
- rt_size_t pa_s,pa_e;
- rt_size_t vaddr;
- rt_size_t pages;
- int ret;
+ size_t l1_off, va_s, va_e;
+ rt_base_t level;
- if(!size)
+ if ((!aspace) || (!vtable))
{
- return 0;
+ return -1;
}
- pa_s = (rt_size_t)p_addr;
- pa_e = ((rt_size_t)p_addr) + size - 1;
- pa_s = GET_PF_ID(pa_s);
- pa_e = GET_PF_ID(pa_e);
- pages = pa_e - pa_s + 1;
+ va_s = (rt_size_t)v_address;
+ va_e = ((rt_size_t)v_address) + size - 1;
- if(v_addr)
+ if (va_e < va_s)
{
- vaddr = (rt_size_t)v_addr;
- pa_s = (rt_size_t)p_addr;
-
- if(GET_PF_OFFSET(vaddr) != GET_PF_OFFSET(pa_s))
- {
- return 0;
- }
+ return -1;
+ }
- vaddr = __UMASKVALUE(vaddr,PAGE_OFFSET_MASK);
+ // convert address to PPN2 index
+ va_s = GET_L1(va_s);
+ va_e = GET_L1(va_e);
- if(check_vaddr(mmu_info,(void *)vaddr,pages) != 0)
- {
- return 0;
- }
- }
- else
+ if (va_s == 0)
{
- vaddr = find_vaddr(mmu_info,pages);
+ return -1;
}
- if(vaddr)
+ // vtable initialization check
+ for (l1_off = va_s; l1_off <= va_e; l1_off++)
{
- ret = __rt_hw_mmu_map(mmu_info,(void *)vaddr,p_addr,pages,attr);
+ size_t v = vtable[l1_off];
- if(ret == 0)
+ if (v)
{
- rt_hw_cpu_tlb_invalidate();
- return (void *)(vaddr | GET_PF_OFFSET((rt_size_t)p_addr));
+ return -1;
}
}
+ rt_aspace_init(&rt_kernel_space, (void *)0x1000, USER_VADDR_START - 0x1000,
+ vtable);
+
+ _init_region(v_address, size);
return 0;
}
-static int __rt_hw_mmu_map_auto(rt_mmu_info *mmu_info,void *v_addr,rt_size_t npages,rt_size_t attr)
+const static int max_level =
+ (ARCH_VADDR_WIDTH - ARCH_PAGE_SHIFT) / ARCH_INDEX_WIDTH;
+
+static inline uintptr_t _get_level_size(int level)
+{
+ return 1ul << (ARCH_PAGE_SHIFT + (max_level - level) * ARCH_INDEX_WIDTH);
+}
+
+static rt_size_t *_query(struct rt_aspace *aspace, void *vaddr, int *level)
{
- rt_size_t loop_va = __UMASKVALUE((rt_size_t)v_addr,PAGE_OFFSET_MASK);
- rt_size_t loop_pa;
- rt_size_t l1_off,l2_off,l3_off;
- rt_size_t *mmu_l1,*mmu_l2,*mmu_l3;
- rt_size_t *ref_cnt;
- rt_size_t i;
- void *va,*pa;
+ rt_size_t l1_off, l2_off, l3_off;
+ rt_size_t *mmu_l1, *mmu_l2, *mmu_l3;
+ rt_size_t pa;
- if(!mmu_info)
- {
- return -1;
- }
+ l1_off = GET_L1((rt_size_t)vaddr);
+ l2_off = GET_L2((rt_size_t)vaddr);
+ l3_off = GET_L3((rt_size_t)vaddr);
- while(npages--)
+ if (!aspace)
{
- loop_pa = (rt_size_t)rt_pages_alloc(0);
+ LOG_W("%s: no aspace", __func__);
+ return RT_NULL;
+ }
- if(!loop_pa)
- {
- goto err;
- }
+ mmu_l1 = ((rt_size_t *)aspace->page_table) + l1_off;
- if(__rt_hw_mmu_map(mmu_info,(void *)loop_va,(void *)loop_pa,1,attr) < 0)
+ if (PTE_USED(*mmu_l1))
+ {
+ if (*mmu_l1 & PTE_XWR_MASK)
{
- goto err;
+ *level = 1;
+ return mmu_l1;
}
- loop_va += PAGE_SIZE;
- }
+ mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1), PV_OFFSET);
- return 0;
-
- err:
- va = (void *)__UMASKVALUE((rt_size_t)v_addr,PAGE_OFFSET_MASK);
-
- for(i = 0;i < npages;i++)
+ if (PTE_USED(*(mmu_l2 + l2_off)))
{
- pa = rt_hw_mmu_v2p(mmu_info,va);
-
- if(pa)
+ if (*(mmu_l2 + l2_off) & PTE_XWR_MASK)
{
- rt_pages_free((void *)PPN_TO_VPN(pa,mmu_info -> pv_off),0);
+ *level = 2;
+ return mmu_l2 + l2_off;
}
- va = (void *)((rt_uint8_t *)va + PAGE_SIZE);
+ mmu_l3 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*(mmu_l2 + l2_off)),
+ PV_OFFSET);
+
+ if (PTE_USED(*(mmu_l3 + l3_off)))
+ {
+ *level = 3;
+ return mmu_l3 + l3_off;
+ }
}
+ }
- __rt_hw_mmu_unmap(mmu_info,v_addr,npages);
- return -1;
+ return RT_NULL;
}
-void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size,rt_size_t attr)
+void *rt_hw_mmu_v2p(struct rt_aspace *aspace, void *vaddr)
{
- rt_size_t vaddr;
- rt_size_t offset;
- rt_size_t pages;
- int ret;
-
- if(!size)
- {
- return 0;
- }
+ int level;
+ uintptr_t *pte = _query(aspace, vaddr, &level);
+ uintptr_t paddr;
- offset = GET_PF_OFFSET((rt_size_t)v_addr);
- size += (offset + PAGE_SIZE - 1);
- pages = size >> PAGE_OFFSET_BIT;
-
- if(v_addr)
+ if (pte)
{
- vaddr = __UMASKVALUE((rt_size_t)v_addr,PAGE_OFFSET_MASK);
-
- if(check_vaddr(mmu_info,(void *)vaddr,pages) != 0)
- {
- return 0;
- }
+ paddr = GET_PADDR(*pte);
+ paddr |= ((intptr_t)vaddr & (_get_level_size(level) - 1));
}
else
{
- vaddr = find_vaddr(mmu_info,pages);
- }
-
- if(vaddr)
- {
- ret = __rt_hw_mmu_map_auto(mmu_info,(void *)vaddr,pages,attr);
-
- if(ret == 0)
- {
- rt_hw_cpu_tlb_invalidate();
- return (void *)(vaddr | offset);
- }
+ paddr = 0;
}
-
- return 0;
+ return (void *)paddr;
}
-void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size)
+static int _noncache(uintptr_t *pte)
{
- rt_size_t va_s,va_e;
- rt_size_t pages;
-
- va_s = ((rt_size_t)v_addr) >> PAGE_OFFSET_BIT;
- va_e = (((rt_size_t)v_addr) + size - 1) >> PAGE_OFFSET_BIT;
- pages = va_e - va_s + 1;
- __rt_hw_mmu_unmap(mmu_info,v_addr,pages);
- rt_hw_cpu_tlb_invalidate();
+ return 0;
}
-void *rt_hw_mmu_map(rt_mmu_info *mmu_info,void *v_addr,void *p_addr,rt_size_t size,rt_size_t attr)
+static int _cache(uintptr_t *pte)
{
- void *ret;
- rt_base_t level;
-
- level = rt_hw_interrupt_disable();
- ret = _rt_hw_mmu_map(mmu_info,v_addr,p_addr,size,attr);
- rt_hw_interrupt_enable(level);
- return ret;
+ return 0;
}
-void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size,rt_size_t attr)
-{
- void *ret;
- rt_base_t level;
-
- level = rt_hw_interrupt_disable();
- ret = _rt_hw_mmu_map_auto(mmu_info,v_addr,size,attr);
- rt_hw_interrupt_enable(level);
- return ret;
-}
+static int (*control_handler[MMU_CNTL_DUMMY_END])(uintptr_t *pte) = {
+ [MMU_CNTL_CACHE] = _cache,
+ [MMU_CNTL_NONCACHE] = _noncache,
+};
-void rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size)
+int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size,
+ enum rt_mmu_cntl cmd)
{
- rt_base_t level;
-
- level = rt_hw_interrupt_disable();
- _rt_hw_mmu_unmap(mmu_info,v_addr,size);
- rt_hw_interrupt_enable(level);
-}
+ int level;
+ int err = -RT_EINVAL;
+ void *vend = vaddr + size;
-void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info,void *v_addr)
-{
- rt_size_t l1_off,l2_off,l3_off;
- rt_size_t *mmu_l1,*mmu_l2,*mmu_l3;
- rt_size_t pa;
+ int (*handler)(uintptr_t * pte);
+ if (cmd >= 0 && cmd < MMU_CNTL_DUMMY_END)
+ {
+ handler = control_handler[cmd];
- l1_off = GET_L1((rt_size_t)v_addr);
- l2_off = GET_L2((rt_size_t)v_addr);
- l3_off = GET_L3((rt_size_t)v_addr);
+ while (vaddr < vend)
+ {
+ uintptr_t *pte = _query(aspace, vaddr, &level);
+ void *range_end = vaddr + _get_level_size(level);
+ RT_ASSERT(range_end < vend);
- if(!mmu_info)
+ if (pte)
+ {
+ err = handler(pte);
+ RT_ASSERT(err == RT_EOK);
+ }
+ vaddr = range_end;
+ }
+ }
+ else
{
- return RT_NULL;
+ err = -RT_ENOSYS;
}
- mmu_l1 = ((rt_size_t *)mmu_info -> vtable) + l1_off;
+ return err;
+}
- if(PTE_USED(*mmu_l1))
+/**
+ * @brief setup Page Table for kernel space. It's a fixed map
+ * and all mappings cannot be changed after initialization.
+ *
+ * Memory region in struct mem_desc must be page aligned,
+ * otherwise is a failure and no report will be
+ * returned.
+ *
+ * @param mmu_info
+ * @param mdesc
+ * @param desc_nr
+ */
+void rt_hw_mmu_setup(rt_aspace_t aspace, struct mem_desc *mdesc, int desc_nr)
+{
+ void *err;
+ for (size_t i = 0; i < desc_nr; i++)
{
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l1));
- mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1),mmu_info -> pv_off);
-
- if(PTE_USED(*(mmu_l2 + l2_off)))
+ size_t attr;
+ switch (mdesc->attr)
{
- RT_ASSERT(!PAGE_IS_LEAF(*(mmu_l2 + l2_off)));
- mmu_l3 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*(mmu_l2 + l2_off)),mmu_info -> pv_off);
-
- if(PTE_USED(*(mmu_l3 + l3_off)))
- {
- RT_ASSERT(PAGE_IS_LEAF(*(mmu_l3 + l3_off)));
- return (void *)(GET_PADDR(*(mmu_l3 + l3_off)) | GET_PF_OFFSET((rt_size_t)v_addr));
- }
+ case NORMAL_MEM:
+ attr = MMU_MAP_K_RWCB;
+ break;
+ case NORMAL_NOCACHE_MEM:
+ attr = MMU_MAP_K_RWCB;
+ break;
+ case DEVICE_MEM:
+ attr = MMU_MAP_K_DEVICE;
+ break;
+ default:
+ attr = MMU_MAP_K_DEVICE;
}
+
+ struct rt_mm_va_hint hint = {.flags = MMF_MAP_FIXED,
+ .limit_start = aspace->start,
+ .limit_range_size = aspace->size,
+ .map_size = mdesc->vaddr_end -
+ mdesc->vaddr_start + 1,
+ .prefer = (void *)mdesc->vaddr_start};
+
+ rt_aspace_map_phy_static(aspace, &mdesc->varea, &hint, attr,
+ mdesc->paddr_start >> MM_PAGE_SHIFT, &err);
+ mdesc++;
}
- return RT_NULL;
+ rt_hw_aspace_switch(&rt_kernel_space);
+ rt_page_cleanup();
}
-void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info,void *v_addr)
+void rt_hw_mmu_kernel_map_init(rt_aspace_t aspace, rt_size_t vaddr_start, rt_size_t size)
{
- void *ret;
- rt_base_t level;
+ rt_size_t paddr_start =
+ __UMASKVALUE(VPN_TO_PPN(vaddr_start, PV_OFFSET), PAGE_OFFSET_MASK);
+ rt_size_t va_s = GET_L1(vaddr_start);
+ rt_size_t va_e = GET_L1(vaddr_start + size - 1);
+ rt_size_t i;
+
+ for (i = va_s; i <= va_e; i++)
+ {
+ MMUTable[i] =
+ COMBINEPTE(paddr_start, PAGE_ATTR_RWX | PTE_G | PTE_V | PTE_CACHE |
+ PTE_SHARE | PTE_BUF | PTE_A | PTE_D);
+ paddr_start += L1_PAGE_SIZE;
+ }
- level = rt_hw_interrupt_disable();
- ret = _rt_hw_mmu_v2p(mmu_info,v_addr);
- rt_hw_interrupt_enable(level);
- return ret;
+ rt_hw_tlb_invalidate_all_local();
}
diff --git a/libcpu/risc-v/t-head/c906/mmu.h b/libcpu/risc-v/t-head/c906/mmu.h
index 09fdc494e7..bb3eb69cd0 100644
--- a/libcpu/risc-v/t-head/c906/mmu.h
+++ b/libcpu/risc-v/t-head/c906/mmu.h
@@ -13,45 +13,83 @@
#include "riscv.h"
#include "riscv_mmu.h"
+#include <mm_aspace.h>
+#include <stddef.h>
+
+/* RAM, Flash, or ROM */
+#define NORMAL_MEM 0
+/* normal nocache memory mapping type */
+#define NORMAL_NOCACHE_MEM 1
+/* MMIO region */
+#define DEVICE_MEM 2
+
+typedef size_t rt_pte_t;
+
struct mem_desc
{
rt_size_t vaddr_start;
rt_size_t vaddr_end;
rt_size_t paddr_start;
rt_size_t attr;
+ struct rt_varea varea;
};
-#define GET_PF_ID(addr) ((addr) >> PAGE_OFFSET_BIT)
-#define GET_PF_OFFSET(addr) __MASKVALUE(addr,PAGE_OFFSET_MASK)
-#define GET_L1(addr) __PARTBIT(addr,VPN2_SHIFT,VPN2_BIT)
-#define GET_L2(addr) __PARTBIT(addr,VPN1_SHIFT,VPN1_BIT)
-#define GET_L3(addr) __PARTBIT(addr,VPN0_SHIFT,VPN0_BIT)
-#define GET_PPN(pte) (__PARTBIT(pte,PTE_PPN_SHIFT,PHYSICAL_ADDRESS_WIDTH_BITS - PTE_PPN_SHIFT))
-#define GET_PADDR(pte) (GET_PPN(pte) << PAGE_OFFSET_BIT)
-#define VPN_TO_PPN(vaddr,pv_off) (((rt_size_t)(vaddr)) + (pv_off))
-#define PPN_TO_VPN(paddr,pv_off) (((rt_size_t)(paddr)) - (pv_off))
-#define COMBINEVADDR(l1_off,l2_off,l3_off) (((l1_off) << VPN2_SHIFT) | ((l2_off) << VPN1_SHIFT) | ((l3_off) << VPN0_SHIFT))
-#define COMBINEPTE(paddr,attr) ((((paddr) >> PAGE_OFFSET_BIT) << PTE_PPN_SHIFT) | (attr))
+#define GET_PF_ID(addr) ((addr) >> PAGE_OFFSET_BIT)
+#define GET_PF_OFFSET(addr) __MASKVALUE(addr, PAGE_OFFSET_MASK)
+#define GET_L1(addr) __PARTBIT(addr, VPN2_SHIFT, VPN2_BIT)
+#define GET_L2(addr) __PARTBIT(addr, VPN1_SHIFT, VPN1_BIT)
+#define GET_L3(addr) __PARTBIT(addr, VPN0_SHIFT, VPN0_BIT)
+#define GET_PPN(pte) \
+ (__PARTBIT(pte, PTE_PPN_SHIFT, PHYSICAL_ADDRESS_WIDTH_BITS - PTE_PPN_SHIFT))
+#define GET_PADDR(pte) (GET_PPN(pte) << PAGE_OFFSET_BIT)
+#define VPN_TO_PPN(vaddr, pv_off) (((rt_size_t)(vaddr)) + (pv_off))
+#define PPN_TO_VPN(paddr, pv_off) (((rt_size_t)(paddr)) - (pv_off))
+#define COMBINEVADDR(l1_off, l2_off, l3_off) \
+ (((l1_off) << VPN2_SHIFT) | ((l2_off) << VPN1_SHIFT) | \
+ ((l3_off) << VPN0_SHIFT))
+#define COMBINEPTE(paddr, attr) \
+ ((((paddr) >> PAGE_OFFSET_BIT) << PTE_PPN_SHIFT) | (attr))
-typedef struct
-{
- size_t *vtable;
- size_t vstart;
- size_t vend;
- size_t pv_off;
-}rt_mmu_info;
+#define ARCH_ADDRESS_WIDTH_BITS 64
+
+#define MMU_MAP_ERROR_VANOTALIGN -1
+#define MMU_MAP_ERROR_PANOTALIGN -2
+#define MMU_MAP_ERROR_NOPAGE -3
+#define MMU_MAP_ERROR_CONFLICT -4
void *rt_hw_mmu_tbl_get();
-void rt_hw_mmu_switch(void *mmu_table);
-int rt_hw_mmu_map_init(rt_mmu_info *mmu_info,void *v_address,rt_size_t size,rt_size_t *vtable,rt_size_t pv_off);
-void rt_hw_mmu_kernel_map_init(rt_mmu_info *mmu_info,rt_size_t vaddr_start,rt_size_t size);
-void *_rt_hw_mmu_map(rt_mmu_info *mmu_info,void *v_addr,void *p_addr,rt_size_t size,rt_size_t attr);
-void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size,rt_size_t attr);
-void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size);
-void *rt_hw_mmu_map(rt_mmu_info *mmu_info,void *v_addr,void *p_addr,rt_size_t size,rt_size_t attr);
-void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size,rt_size_t attr);
-void rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size);
-void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info,void *v_addr);
-void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info,void *v_addr);
+int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, rt_size_t size,
+ rt_size_t *vtable, rt_size_t pv_off);
+void rt_hw_mmu_setup(rt_aspace_t aspace, struct mem_desc *mdesc, int desc_nr);
+void rt_hw_mmu_kernel_map_init(rt_aspace_t aspace, rt_size_t vaddr_start,
+ rt_size_t size);
+void *rt_hw_mmu_map(rt_aspace_t aspace, void *v_addr, void *p_addr, size_t size,
+ size_t attr);
+void rt_hw_mmu_unmap(rt_aspace_t aspace, void *v_addr, size_t size);
+void rt_hw_aspace_switch(rt_aspace_t aspace);
+void *rt_hw_mmu_v2p(rt_aspace_t aspace, void *vaddr);
+
+static inline void *_rt_kmem_v2p(void *vaddr)
+{
+ return rt_hw_mmu_v2p(&rt_kernel_space, vaddr);
+}
+
+static inline void *rt_kmem_v2p(void *vaddr)
+{
+ MM_PGTBL_LOCK(&rt_kernel_space);
+ void *paddr = _rt_kmem_v2p(vaddr);
+ MM_PGTBL_UNLOCK(&rt_kernel_space);
+ return paddr;
+}
+
+enum rt_mmu_cntl
+{
+ MMU_CNTL_NONCACHE,
+ MMU_CNTL_CACHE,
+ MMU_CNTL_DUMMY_END,
+};
+
+int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size,
+ enum rt_mmu_cntl cmd);
#endif
diff --git a/libcpu/risc-v/t-head/c906/riscv_mmu.c b/libcpu/risc-v/t-head/c906/riscv_mmu.c
index 9ba48e34c4..e648c52269 100644
--- a/libcpu/risc-v/t-head/c906/riscv_mmu.c
+++ b/libcpu/risc-v/t-head/c906/riscv_mmu.c
@@ -18,20 +18,12 @@
#include "riscv_mmu.h"
-void mmu_set_pagetable(rt_ubase_t addr)
-{
- RT_ASSERT(__CHECKALIGN(addr,PAGE_OFFSET_BIT));
- RT_ASSERT(__CHECKUPBOUND(addr,PHYSICAL_ADDRESS_WIDTH_BITS));
- write_csr(satp,(((size_t)8) << 60) | (addr >> PAGE_OFFSET_BIT));
- mmu_flush_tlb();
-}
-
void mmu_enable_user_page_access()
{
- set_csr(sstatus,SSTATUS_PUM);
+ set_csr(sstatus,SSTATUS_SUM);
}
void mmu_disable_user_page_access()
{
- clear_csr(sstatus,SSTATUS_PUM);
+ clear_csr(sstatus,SSTATUS_SUM);
}
diff --git a/libcpu/risc-v/t-head/c906/riscv_mmu.h b/libcpu/risc-v/t-head/c906/riscv_mmu.h
index 138bd596e9..386bda9884 100644
--- a/libcpu/risc-v/t-head/c906/riscv_mmu.h
+++ b/libcpu/risc-v/t-head/c906/riscv_mmu.h
@@ -12,8 +12,8 @@
#ifndef __RISCV_MMU_H__
#define __RISCV_MMU_H__
-#include <rthw.h>
#include <rtthread.h>
+#include <rthw.h>
#include "riscv.h"
#undef PAGE_SIZE
@@ -59,21 +59,42 @@
#define PAGE_ATTR_USER (PTE_U)
#define PAGE_ATTR_SYSTEM (0)
-#define PAGE_DEFAULT_ATTR_LEAF (PAGE_ATTR_RWX | PAGE_ATTR_USER | PTE_V | PTE_G | PTE_SHARE | PTE_BUF | PTE_CACHE | PTE_A | PTE_D)
-#define PAGE_DEFAULT_ATTR_NEXT (PAGE_ATTR_NEXT_LEVEL | PTE_V | PTE_G | PTE_SHARE | PTE_BUF | PTE_CACHE | PTE_A | PTE_D)
+#define PAGE_DEFAULT_ATTR_LEAF (PAGE_ATTR_RWX | PAGE_ATTR_USER | PTE_V | PTE_G)
+#define PAGE_DEFAULT_ATTR_NEXT (PAGE_ATTR_NEXT_LEVEL | PTE_V | PTE_G)
+
+#define PAGE_IS_LEAF(pte) __MASKVALUE(pte, PAGE_ATTR_RWX)
+
+#define PTE_USED(pte) __MASKVALUE(pte, PTE_V)
+
+/**
+ * encoding of SATP (Supervisor Address Translation and Protection register)
+ */
+#define SATP_MODE_OFFSET 60
+#define SATP_MODE_BARE 0
+#define SATP_MODE_SV39 8
+#define SATP_MODE_SV48 9
+#define SATP_MODE_SV57 10
+#define SATP_MODE_SV64 11
+
+#define ARCH_VADDR_WIDTH 39
+#define SATP_MODE SATP_MODE_SV39
-#define PAGE_IS_LEAF(pte) __MASKVALUE(pte,PAGE_ATTR_RWX)
+#define MMU_MAP_K_DEVICE (PTE_G | PTE_W | PTE_R | PTE_V)
+#define MMU_MAP_K_RWCB (PTE_G | PTE_X | PTE_W | PTE_R | PTE_V)
+#define MMU_MAP_U_RWCB (PTE_U | PTE_X | PTE_W | PTE_R | PTE_V)
+#define MMU_MAP_U_RWCB_XN (PTE_U | PTE_W | PTE_R | PTE_V)
+#define MMU_MAP_U_RW (PTE_U | PTE_X | PTE_W | PTE_R | PTE_V)
-#define PTE_USED(pte) __MASKVALUE(pte,PTE_V)
+#define PTE_XWR_MASK 0xe
-#define mmu_flush_tlb() do{asm volatile("sfence.vma x0,x0");}while(0)
+#define ARCH_PAGE_SIZE PAGE_SIZE
+#define ARCH_PAGE_MASK (ARCH_PAGE_SIZE - 1)
+#define ARCH_PAGE_SHIFT PAGE_OFFSET_BIT
+#define ARCH_INDEX_WIDTH 9
+#define ARCH_INDEX_SIZE (1ul << ARCH_INDEX_WIDTH)
+#define ARCH_INDEX_MASK (ARCH_INDEX_SIZE - 1)
-//compatible to rt-smart new version
-#define MMU_MAP_K_DEVICE (PAGE_ATTR_RWX | PTE_V | PTE_G | PTE_SO | PTE_BUF | PTE_A | PTE_D)
-#define MMU_MAP_K_RWCB (PAGE_ATTR_RWX | PTE_V | PTE_G | PTE_SHARE | PTE_BUF | PTE_CACHE | PTE_A | PTE_D)
-#define ARCH_PAGE_SIZE PAGE_SIZE
-#define ARCH_PAGE_MASK (ARCH_PAGE_SIZE - 1)
-#define ARCH_PAGE_SHIFT PAGE_OFFSET_BIT
+#define ARCH_MAP_FAILED ((void *)0x8000000000000000)
void mmu_set_pagetable(rt_ubase_t addr);
void mmu_enable_user_page_access();
diff --git a/libcpu/risc-v/t-head/c906/sbi.c b/libcpu/risc-v/t-head/c906/sbi.c
index f848ec7810..e4577e8f05 100644
--- a/libcpu/risc-v/t-head/c906/sbi.c
+++ b/libcpu/risc-v/t-head/c906/sbi.c
@@ -36,12 +36,12 @@
*/
#include "sbi.h"
-#include <stdbool.h>
#include <rtthread.h>
+#include <stdbool.h>
/* SBI Implementation-Specific Definitions */
-#define OPENSBI_VERSION_MAJOR_OFFSET 16
-#define OPENSBI_VERSION_MINOR_MASK 0xFFFF
+#define OPENSBI_VERSION_MAJOR_OFFSET 16
+#define OPENSBI_VERSION_MINOR_MASK 0xFFFF
unsigned long sbi_spec_version;
unsigned long sbi_impl_id;
@@ -51,26 +51,22 @@ static bool has_time_extension = false;
static bool has_ipi_extension = false;
static bool has_rfnc_extension = false;
-static struct sbi_ret
-sbi_get_spec_version(void)
+static struct sbi_ret sbi_get_spec_version(void)
{
return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_SPEC_VERSION));
}
-static struct sbi_ret
-sbi_get_impl_id(void)
+static struct sbi_ret sbi_get_impl_id(void)
{
return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_IMPL_ID));
}
-static struct sbi_ret
-sbi_get_impl_version(void)
+static struct sbi_ret sbi_get_impl_version(void)
{
return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_IMPL_VERSION));
}
-void
-sbi_print_version(void)
+void sbi_print_version(void)
{
u_int major;
u_int minor;
@@ -89,7 +85,8 @@ sbi_print_version(void)
rt_kprintf("SBI: Berkely Boot Loader %lu\n", sbi_impl_version);
break;
case (SBI_IMPL_ID_XVISOR):
- rt_kprintf("SBI: eXtensible Versatile hypervISOR %lu\n", sbi_impl_version);
+ rt_kprintf("SBI: eXtensible Versatile hypervISOR %lu\n",
+ sbi_impl_version);
break;
case (SBI_IMPL_ID_KVM):
rt_kprintf("SBI: Kernel-based Virtual Machine %lu\n", sbi_impl_version);
@@ -116,8 +113,7 @@ sbi_print_version(void)
rt_kprintf("SBI Specification Version: %u.%u\n", major, minor);
}
-void
-sbi_set_timer(uint64_t val)
+void sbi_set_timer(uint64_t val)
{
struct sbi_ret ret;
@@ -133,16 +129,14 @@ sbi_set_timer(uint64_t val)
}
}
-void
-sbi_send_ipi(const unsigned long *hart_mask)
+void sbi_send_ipi(const unsigned long *hart_mask)
{
struct sbi_ret ret;
/* Use the IPI legacy replacement extension, if available. */
if (has_ipi_extension)
{
- ret = SBI_CALL2(SBI_EXT_ID_IPI, SBI_IPI_SEND_IPI,
- *hart_mask, 0);
+ ret = SBI_CALL2(SBI_EXT_ID_IPI, SBI_IPI_SEND_IPI, *hart_mask, 0);
RT_ASSERT(ret.error == SBI_SUCCESS);
}
else
@@ -151,16 +145,15 @@ sbi_send_ipi(const unsigned long *hart_mask)
}
}
-void
-sbi_remote_fence_i(const unsigned long *hart_mask)
+void sbi_remote_fence_i(const unsigned long *hart_mask)
{
struct sbi_ret ret;
/* Use the RFENCE legacy replacement extension, if available. */
if (has_rfnc_extension)
{
- ret = SBI_CALL2(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_FENCE_I,
- *hart_mask, 0);
+ ret =
+ SBI_CALL2(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_FENCE_I, *hart_mask, 0);
RT_ASSERT(ret.error == SBI_SUCCESS);
}
else
@@ -169,28 +162,29 @@ sbi_remote_fence_i(const unsigned long *hart_mask)
}
}
-void
-sbi_remote_sfence_vma(const unsigned long *hart_mask, unsigned long start, unsigned long size)
+int sbi_remote_sfence_vma(const unsigned long *hart_mask,
+ const unsigned long hart_mask_base,
+ unsigned long start, unsigned long size)
{
- struct sbi_ret ret;
+ struct sbi_ret ret = {.error = SBI_SUCCESS};
/* Use the RFENCE legacy replacement extension, if available. */
if (has_rfnc_extension)
{
- ret = SBI_CALL4(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_SFENCE_VMA,
- *hart_mask, 0, start, size);
- RT_ASSERT(ret.error == SBI_SUCCESS);
+ ret = SBI_CALL4(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_SFENCE_VMA, *hart_mask,
+ hart_mask_base, start, size);
}
else
{
- (void)SBI_CALL3(SBI_REMOTE_SFENCE_VMA, 0, (uint64_t)hart_mask,
- start, size);
+ (void)SBI_CALL3(SBI_REMOTE_SFENCE_VMA, 0, (uint64_t)hart_mask, start,
+ size);
}
+ return ret.error;
}
-void
-sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long start, unsigned long size,
- unsigned long asid)
+void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
+ unsigned long start, unsigned long size,
+ unsigned long asid)
{
struct sbi_ret ret;
@@ -203,13 +197,13 @@ sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long start,
}
else
{
- (void)SBI_CALL4(SBI_REMOTE_SFENCE_VMA_ASID, 0,
- (uint64_t)hart_mask, start, size, asid);
+ (void)SBI_CALL4(SBI_REMOTE_SFENCE_VMA_ASID, 0, (uint64_t)hart_mask,
+ start, size, asid);
}
}
-int
-sbi_hsm_hart_start(unsigned long hart, unsigned long start_addr, unsigned long priv)
+int sbi_hsm_hart_start(unsigned long hart, unsigned long start_addr,
+ unsigned long priv)
{
struct sbi_ret ret;
@@ -217,14 +211,12 @@ sbi_hsm_hart_start(unsigned long hart, unsigned long start_addr, unsigned long p
return (ret.error != 0 ? (int)ret.error : 0);
}
-void
-sbi_hsm_hart_stop(void)
+void sbi_hsm_hart_stop(void)
{
(void)SBI_CALL0(SBI_EXT_ID_HSM, SBI_HSM_HART_STOP);
}
-int
-sbi_hsm_hart_status(unsigned long hart)
+int sbi_hsm_hart_status(unsigned long hart)
{
struct sbi_ret ret;
@@ -233,8 +225,7 @@ sbi_hsm_hart_status(unsigned long hart)
return (ret.error != 0 ? (int)ret.error : (int)ret.value);
}
-void
-sbi_init(void)
+void sbi_init(void)
{
struct sbi_ret sret;
@@ -263,3 +254,11 @@ sbi_init(void)
if (sbi_probe_extension(SBI_EXT_ID_RFNC) != 0)
has_rfnc_extension = true;
}
+
+void rt_hw_console_output(const char *str)
+{
+ while (*str)
+ {
+ sbi_console_putchar(*str++);
+ }
+}
diff --git a/libcpu/risc-v/t-head/c906/sbi.h b/libcpu/risc-v/t-head/c906/sbi.h
index 0e95ede334..ed29ecfd20 100644
--- a/libcpu/risc-v/t-head/c906/sbi.h
+++ b/libcpu/risc-v/t-head/c906/sbi.h
@@ -140,7 +140,7 @@ struct sbi_ret
long value;
};
-static __inline struct sbi_ret
+static inline struct sbi_ret
sbi_call(uint64_t arg7, uint64_t arg6, uint64_t arg0, uint64_t arg1,
uint64_t arg2, uint64_t arg3, uint64_t arg4)
{
@@ -184,7 +184,9 @@ void sbi_send_ipi(const unsigned long *hart_mask);
/* RFENCE extension functions. */
void sbi_remote_fence_i(const unsigned long *hart_mask);
-void sbi_remote_sfence_vma(const unsigned long *hart_mask, unsigned long start, unsigned long size);
+int sbi_remote_sfence_vma(const unsigned long *hart_mask,
+ const unsigned long hart_mask_base,
+ unsigned long start, unsigned long size);
void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long start,
unsigned long size, unsigned long asid);
diff --git a/libcpu/risc-v/t-head/c906/tlb.h b/libcpu/risc-v/t-head/c906/tlb.h
new file mode 100644
index 0000000000..5bdf18c189
--- /dev/null
+++ b/libcpu/risc-v/t-head/c906/tlb.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-11-28 WangXiaoyao the first version
+ */
+#ifndef __TLB_H__
+#define __TLB_H__
+
+#include "mm_aspace.h"
+#include "riscv_mmu.h"
+#include "rtdbg.h"
+#include "rtthread.h"
+#include <sbi.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#define HANDLE_FAULT(ret) \
+ if (__builtin_expect((ret) != SBI_SUCCESS, 0)) \
+ LOG_W("%s failed", __FUNCTION__);
+
+static inline void rt_hw_tlb_invalidate_all(void)
+{
+ uintptr_t mask = -1ul;
+ HANDLE_FAULT(sbi_remote_sfence_vma(&mask, -1ul, 0, mask));
+}
+
+static inline void rt_hw_tlb_invalidate_all_local(void)
+{
+ __asm__ volatile("sfence.vma" ::: "memory");
+}
+
+static inline void rt_hw_tlb_invalidate_aspace(rt_aspace_t aspace)
+{
+ // TODO ASID
+ rt_hw_tlb_invalidate_all_local();
+}
+
+static inline void rt_hw_tlb_invalidate_page(rt_aspace_t aspace, void *start)
+{
+ __asm__ volatile("sfence.vma %0, zero" ::"r"(start) : "memory");
+}
+
+static inline void rt_hw_tlb_invalidate_range(rt_aspace_t aspace, void *start,
+ size_t size, size_t stride)
+{
+ // huge page is taking as normal page
+ if (size <= ARCH_PAGE_SIZE)
+ {
+ rt_hw_tlb_invalidate_page(aspace, start);
+ }
+ else
+ {
+ rt_hw_tlb_invalidate_aspace(aspace);
+ }
+}
+
+#endif /* __TLB_H__ */
diff --git a/libcpu/risc-v/t-head/c906/trap.c b/libcpu/risc-v/t-head/c906/trap.c
index beca180831..541d24377b 100644
--- a/libcpu/risc-v/t-head/c906/trap.c
+++ b/libcpu/risc-v/t-head/c906/trap.c
@@ -107,7 +107,7 @@ void dump_regs(struct rt_hw_stack_frame *regs)
rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_SIE) ? "Supervisor Interrupt Enabled" : "Supervisor Interrupt Disabled");
rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_SPIE) ? "Last Time Supervisor Interrupt Enabled" : "Last Time Supervisor Interrupt Disabled");
rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_SPP) ? "Last Privilege is Supervisor Mode" : "Last Privilege is User Mode");
- rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_PUM) ? "Permit to Access User Page" : "Not Permit to Access User Page");
+ rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_SUM) ? "Permit to Access User Page" : "Not Permit to Access User Page");
rt_kprintf("\t%s\n",(regs->sstatus & (1 << 19)) ? "Permit to Read Executable-only Page" : "Not Permit to Read Executable-only Page");
rt_size_t satp_v = read_csr(satp);
rt_kprintf("satp = 0x%p\n",satp_v);
@@ -202,6 +202,45 @@ void generic_handle_irq(int irq)
plic_complete(irq);
}
+static const char *get_exception_msg(int id)
+{
+ const char *msg;
+ if (id < sizeof(Exception_Name) / sizeof(const char *))
+ {
+ msg = Exception_Name[id];
+ }
+ else
+ {
+ msg = "Unknown Exception";
+ }
+ return msg;
+}
+
+void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw_stack_frame *sp)
+{
+ rt_size_t id = __MASKVALUE(scause, __MASK(63UL));
+
+#ifdef RT_USING_USERSPACE
+ /* user page fault */
+ if (id == EP_LOAD_PAGE_FAULT ||
+ id == EP_STORE_PAGE_FAULT)
+ {
+ if (arch_expand_user_stack((void *)stval))
+ {
+ return;
+ }
+ }
+#endif
+ LOG_E("[FATAL ERROR] Exception %ld:%s", id, get_exception_msg(id));
+ LOG_E("scause:0x%p,stval:0x%p,sepc:0x%p", scause, stval, sepc);
+ dump_regs(sp);
+
+ rt_hw_backtrace((uint32_t *)sp->s0_fp, sepc);
+
+ LOG_E("User Fault, killing thread: %s", rt_thread_self()->name);
+ sys_exit(-1);
+}
+
/* Trap entry */
void handle_trap(rt_size_t scause,rt_size_t stval,rt_size_t sepc,struct rt_hw_stack_frame *sp)
{
@@ -238,28 +277,28 @@ void handle_trap(rt_size_t scause,rt_size_t stval,rt_size_t sepc,struct rt_hw_st
}
else
{
-#ifdef RT_USING_SMART
- /* page fault */
- if (id == EP_LOAD_PAGE_FAULT ||
- id == EP_STORE_PAGE_FAULT)
- {
- arch_expand_user_stack((void *)stval);
- return;
- }
-#endif
- if(id < sizeof(Exception_Name) / sizeof(const char *))
- {
- msg = Exception_Name[id];
- }
- else
+ if (!(sp->sstatus & 0x100))
{
- msg = "Unknown Exception";
+ handle_user(scause, stval, sepc, sp);
+ // after handle_user(), return to user space.
+ // otherwise it never returns
+ return ;
}
- rt_kprintf("Unhandled Exception %ld:%s\n",id,msg);
+ // handle kernel exception:
+ rt_kprintf("Unhandled Exception %ld:%s\n", id, get_exception_msg(id));
}
- rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n",scause,stval,sepc);
+ rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n", scause, stval, sepc);
dump_regs(sp);
- while(1);
+ rt_kprintf("--------------Thread list--------------\n");
+ rt_kprintf("current thread: %s\n", rt_thread_self()->name);
+ list_process();
+
+ extern struct rt_thread *rt_current_thread;
+ rt_kprintf("--------------Backtrace--------------\n");
+ rt_hw_backtrace((uint32_t *)sp->s0_fp, sepc);
+
+ while (1)
+ ;
}
diff --git a/libcpu/risc-v/virt64/backtrace.c b/libcpu/risc-v/virt64/backtrace.c
index 11651daa16..ad5dd7d2d3 100644
--- a/libcpu/risc-v/virt64/backtrace.c
+++ b/libcpu/risc-v/virt64/backtrace.c
@@ -16,11 +16,10 @@
extern rt_ubase_t __text_start[];
extern rt_ubase_t __text_end[];
-static char *_get_elf_name();
+static char *_get_elf_name(size_t sepc);
void rt_hw_backtrace(rt_uint32_t *ffp, rt_ubase_t sepc)
{
- extern rt_mmu_info mmu_info;
rt_ubase_t *ra;
rt_ubase_t *fp;
rt_ubase_t vas, vae;
@@ -60,13 +59,13 @@ void rt_hw_backtrace(rt_uint32_t *ffp, rt_ubase_t sepc)
}
ra = fp - 1;
- if (!_rt_hw_mmu_v2p(&mmu_info, ra) || *ra < vas || *ra > vae)
+ if (!_rt_kmem_v2p(ra) || *ra < vas || *ra > vae)
break;
rt_kprintf(" %p", *ra - 0x04);
fp = fp - 2;
- if (!_rt_hw_mmu_v2p(&mmu_info, fp))
+ if (!_rt_kmem_v2p(fp))
break;
fp = (rt_ubase_t *)(*fp);
if (!fp)
diff --git a/libcpu/risc-v/virt64/context_gcc.S b/libcpu/risc-v/virt64/context_gcc.S
index c1fe828822..0f3f2e08a5 100644
--- a/libcpu/risc-v/virt64/context_gcc.S
+++ b/libcpu/risc-v/virt64/context_gcc.S
@@ -80,7 +80,7 @@ rt_hw_context_switch_to:
#ifdef RT_USING_SMART
mv a0, s1
- jal lwp_mmu_switch
+ jal lwp_aspace_switch
#endif
RESTORE_CONTEXT
@@ -108,7 +108,7 @@ rt_hw_context_switch:
#ifdef RT_USING_SMART
mv a0, s1
- jal lwp_mmu_switch
+ jal lwp_aspace_switch
#endif
RESTORE_CONTEXT
diff --git a/libcpu/risc-v/virt64/mmu.c b/libcpu/risc-v/virt64/mmu.c
index 3a9daee3dc..17760c8779 100644
--- a/libcpu/risc-v/virt64/mmu.c
+++ b/libcpu/risc-v/virt64/mmu.c
@@ -6,282 +6,72 @@
* Change Logs:
* Date Author Notes
* 2021-01-30 lizhirui first version
+ * 2022-12-13 WangXiaoyao Port to new mm
*/
#include <rtthread.h>
-#include <rthw.h>
+#include <stddef.h>
+#include <stdint.h>
-#ifdef RT_USING_SMART
-
-#include <board.h>
-#include <page.h>
-#include <stdlib.h>
-#include <string.h>
-#include <lwp_mm.h>
#include <cache.h>
+#include <mm_aspace.h>
+#include <mm_page.h>
+#include <mmu.h>
+#include <riscv_mmu.h>
+#include <tlb.h>
-#define DBG_TAG "mmu"
-#define DBG_LVL DBG_INFO
-#include <rtdbg.h>
-
-#include "riscv.h"
-#include "riscv_mmu.h"
-#include "mmu.h"
-
-void *current_mmu_table = RT_NULL;
-
-volatile rt_ubase_t MMUTable[__SIZE(VPN2_BIT)] __attribute__((aligned(4 * 1024)));
-
-static void rt_hw_cpu_tlb_invalidate()
-{
- rt_size_t satpv = read_csr(satp);
- write_csr(satp, satpv);
- mmu_flush_tlb();
-}
-
-void *rt_hw_mmu_tbl_get()
-{
- return current_mmu_table;
-}
-
-void rt_hw_mmu_switch(void *mmu_table)
-{
- current_mmu_table = mmu_table;
- RT_ASSERT(__CHECKALIGN(mmu_table, PAGE_OFFSET_BIT));
- mmu_set_pagetable((rt_ubase_t)mmu_table);
- rt_hw_cpu_dcache_clean_all();
- rt_hw_cpu_icache_invalidate_all();
-}
-
-int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void *v_address, rt_size_t size, rt_size_t *vtable, rt_size_t pv_off)
-{
- size_t l1_off, va_s, va_e;
- rt_base_t level;
-
- if ((!mmu_info) || (!vtable))
- {
- return -1;
- }
-
- va_s = (rt_size_t)v_address;
- va_e = ((rt_size_t)v_address) + size - 1;
-
- if (va_e < va_s)
- {
- return -1;
- }
-
- // convert address to PPN2 index
- va_s = GET_L1(va_s);
- va_e = GET_L1(va_e);
-
- if (va_s == 0)
- {
- return -1;
- }
-
- rt_mm_lock();
-
- // vtable initialization check
- for (l1_off = va_s; l1_off <= va_e; l1_off++)
- {
- size_t v = vtable[l1_off];
-
- if (v)
- {
- rt_mm_unlock();
- return -1;
- }
- }
-
- rt_mm_unlock();
- mmu_info->vtable = vtable;
- mmu_info->vstart = va_s;
- mmu_info->vend = va_e;
- mmu_info->pv_off = pv_off;
-
- return 0;
-}
-
-void rt_hw_mmu_kernel_map_init(rt_mmu_info *mmu_info, rt_size_t vaddr_start, rt_size_t size)
-{
- rt_size_t paddr_start = __UMASKVALUE(VPN_TO_PPN(vaddr_start, mmu_info->pv_off), PAGE_OFFSET_MASK);
- rt_size_t va_s = GET_L1(vaddr_start);
- rt_size_t va_e = GET_L1(vaddr_start + size - 1);
- rt_size_t i;
-
- for (i = va_s; i <= va_e; i++)
- {
- mmu_info->vtable[i] = COMBINEPTE(paddr_start, PAGE_ATTR_RWX | PTE_G | PTE_V);
- paddr_start += L1_PAGE_SIZE;
- }
+#ifdef RT_USING_SMART
+#include <ioremap.h>
+#include <lwp_user_mm.h>
+#include <tlb.h>
+#endif
- rt_hw_cpu_tlb_invalidate();
-}
+#define DBG_TAG "hw.mmu"
+#define DBG_LVL DBG_LOG
+#include <rtdbg.h>
-// find a range of free virtual address specified by pages
-static size_t find_vaddr(rt_mmu_info *mmu_info, int pages)
-{
- size_t loop_pages;
- size_t va;
- size_t find_va = 0;
- int n = 0;
- size_t i;
+#ifndef RT_USING_SMART
+#define PV_OFFSET 0
+#define USER_VADDR_START 0
+#endif
- if (!pages || !mmu_info)
- {
- return 0;
- }
+static size_t _unmap_area(struct rt_aspace *aspace, void *v_addr, size_t size);
- loop_pages = (mmu_info->vend - mmu_info->vstart) ? (mmu_info->vend - mmu_info->vstart) : 1;
- loop_pages <<= (ARCH_INDEX_WIDTH * 2);
- va = mmu_info->vstart;
- va <<= (ARCH_PAGE_SHIFT + ARCH_INDEX_WIDTH * 2);
+static void *current_mmu_table = RT_NULL;
- for (i = 0; i < loop_pages; i++, va += ARCH_PAGE_SIZE)
- {
- if (_rt_hw_mmu_v2p(mmu_info, (void *)va))
- {
- n = 0;
- find_va = 0;
- continue;
- }
- if (!find_va)
- {
- find_va = va;
- }
- n++;
- if (n >= pages)
- {
- return find_va;
- }
- }
- return 0;
-}
+volatile __attribute__((aligned(4 * 1024)))
+rt_ubase_t MMUTable[__SIZE(VPN2_BIT)];
-// check whether the range of virtual address are free
-static int check_vaddr(rt_mmu_info *mmu_info, void *va, rt_size_t pages)
+void rt_hw_aspace_switch(rt_aspace_t aspace)
{
- rt_size_t loop_va = __UMASKVALUE((rt_size_t)va, PAGE_OFFSET_MASK);
- rt_size_t l1_off, l2_off, l3_off;
- rt_size_t *mmu_l1, *mmu_l2, *mmu_l3;
-
- if (!pages)
- {
- return -1;
- }
-
- if (!mmu_info)
- {
- return -1;
- }
-
- while (pages--)
- {
- l1_off = GET_L1(loop_va);
- l2_off = GET_L2(loop_va);
- l3_off = GET_L3(loop_va);
- mmu_l1 = ((rt_size_t *)mmu_info->vtable) + l1_off;
-
- if (PTE_USED(*mmu_l1))
- {
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l1));
- mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1), mmu_info->pv_off) + l2_off;
-
- if (PTE_USED(*mmu_l2))
- {
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l2));
- mmu_l3 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l2), mmu_info->pv_off) + l3_off;
-
- if (PTE_USED(*mmu_l3))
- {
- RT_ASSERT(PAGE_IS_LEAF(*mmu_l3));
- return -1;
- }
- }
- }
+ uintptr_t page_table = (uintptr_t)_rt_kmem_v2p(aspace->page_table);
+ current_mmu_table = aspace->page_table;
- loop_va += PAGE_SIZE;
- }
-
- return 0;
+ write_csr(satp, (((size_t)SATP_MODE) << SATP_MODE_OFFSET) |
+ ((rt_ubase_t)page_table >> PAGE_OFFSET_BIT));
+ rt_hw_tlb_invalidate_all_local();
}
-static void __rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, rt_size_t npages)
+void *rt_hw_mmu_tbl_get()
{
- rt_size_t loop_va = __UMASKVALUE((rt_size_t)v_addr, PAGE_OFFSET_MASK);
- rt_size_t l1_off, l2_off, l3_off;
- rt_size_t *mmu_l1, *mmu_l2, *mmu_l3;
-
- RT_ASSERT(mmu_info);
-
- while (npages--)
- {
- l1_off = (rt_size_t)GET_L1(loop_va);
- RT_ASSERT((l1_off >= mmu_info->vstart) && (l1_off <= mmu_info->vend));
- l2_off = (rt_size_t)GET_L2(loop_va);
- l3_off = (rt_size_t)GET_L3(loop_va);
-
- mmu_l1 = ((rt_size_t *)mmu_info->vtable) + l1_off;
- RT_ASSERT(PTE_USED(*mmu_l1))
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l1));
- mmu_l2 = ((rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1), mmu_info->pv_off)) + l2_off;
- RT_ASSERT(PTE_USED(*mmu_l2));
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l2));
- mmu_l3 = ((rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l2), mmu_info->pv_off)) + l3_off;
- RT_ASSERT(PTE_USED(*mmu_l3));
- RT_ASSERT(PAGE_IS_LEAF(*(mmu_l3)));
-
- *mmu_l3 = 0;
- rt_hw_cpu_dcache_clean(mmu_l3, sizeof(*mmu_l3));
-
- // decrease reference from leaf page to l3 page
- mmu_l3 -= l3_off;
- rt_pages_free(mmu_l3, 0);
- int free = rt_page_ref_get(mmu_l3, 0);
-
- if (free == 1)
- {
- // free l3 page
- rt_pages_free(mmu_l3, 0);
-
- *mmu_l2 = 0;
- rt_hw_cpu_dcache_clean(mmu_l2, sizeof(*mmu_l2));
-
- // decrease reference from l3 page to l2 page
- mmu_l2 -= l2_off;
- rt_pages_free(mmu_l2, 0);
-
- free = rt_page_ref_get(mmu_l2, 0);
- if (free == 1)
- {
- // free l3 page
- rt_pages_free(mmu_l2, 0);
- // reset PTE in l1
- *mmu_l1 = 0;
- rt_hw_cpu_dcache_clean(mmu_l1, sizeof(*mmu_l1));
- }
- }
-
- loop_va += PAGE_SIZE;
- }
+ return current_mmu_table;
}
-static int _mmu_map_one_page(rt_mmu_info *mmu_info, size_t va, size_t pa, size_t attr)
+static int _map_one_page(struct rt_aspace *aspace, void *va, void *pa,
+ size_t attr)
{
rt_size_t l1_off, l2_off, l3_off;
rt_size_t *mmu_l1, *mmu_l2, *mmu_l3;
- l1_off = GET_L1(va);
- l2_off = GET_L2(va);
- l3_off = GET_L3(va);
+ l1_off = GET_L1((size_t)va);
+ l2_off = GET_L2((size_t)va);
+ l3_off = GET_L3((size_t)va);
- mmu_l1 = ((rt_size_t *)mmu_info->vtable) + l1_off;
+ mmu_l1 = ((rt_size_t *)aspace->page_table) + l1_off;
if (PTE_USED(*mmu_l1))
{
- RT_ASSERT(!PAGE_IS_LEAF(*mmu_l1));
- mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1), mmu_info->pv_off);
+ mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1), PV_OFFSET);
}
else
{
@@ -291,7 +81,8 @@ static int _mmu_map_one_page(rt_mmu_info *mmu_info, size_t va, size_t pa, size_t
{
rt_memset(mmu_l2, 0, PAGE_SIZE);
rt_hw_cpu_dcache_clean(mmu_l2, PAGE_SIZE);
- *mmu_l1 = COMBINEPTE((rt_size_t)VPN_TO_PPN(mmu_l2, mmu_info->pv_off), PAGE_DEFAULT_ATTR_NEXT);
+ *mmu_l1 = COMBINEPTE((rt_size_t)VPN_TO_PPN(mmu_l2, PV_OFFSET),
+ PAGE_DEFAULT_ATTR_NEXT);
rt_hw_cpu_dcache_clean(mmu_l1, sizeof(*mmu_l1));
}
else
@@ -303,7 +94,8 @@ static int _mmu_map_one_page(rt_mmu_info *mmu_info, size_t va, size_t pa, size_t
if (PTE_USED(*(mmu_l2 + l2_off)))
{
RT_ASSERT(!PAGE_IS_LEAF(*(mmu_l2 + l2_off)));
- mmu_l3 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*(mmu_l2 + l2_off)), mmu_info->pv_off);
+ mmu_l3 =
+ (rt_size_t *)PPN_TO_VPN(GET_PADDR(*(mmu_l2 + l2_off)), PV_OFFSET);
}
else
{
@@ -313,7 +105,9 @@ static int _mmu_map_one_page(rt_mmu_info *mmu_info, size_t va, size_t pa, size_t
{
rt_memset(mmu_l3, 0, PAGE_SIZE);
rt_hw_cpu_dcache_clean(mmu_l3, PAGE_SIZE);
- *(mmu_l2 + l2_off) = COMBINEPTE((rt_size_t)VPN_TO_PPN(mmu_l3, mmu_info->pv_off), PAGE_DEFAULT_ATTR_NEXT);
+ *(mmu_l2 + l2_off) =
+ COMBINEPTE((rt_size_t)VPN_TO_PPN(mmu_l3, PV_OFFSET),
+ PAGE_DEFAULT_ATTR_NEXT);
rt_hw_cpu_dcache_clean(mmu_l2, sizeof(*mmu_l2));
// declares a reference to parent page table
rt_page_ref_inc((void *)mmu_l2, 0);
@@ -332,259 +126,242 @@ static int _mmu_map_one_page(rt_mmu_info *mmu_info, size_t va, size_t pa, size_t
return 0;
}
-static int __rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, rt_size_t npages, rt_size_t attr)
+/** rt_hw_mmu_map will never override existed page table entry */
+void *rt_hw_mmu_map(struct rt_aspace *aspace, void *v_addr, void *p_addr,
+ size_t size, size_t attr)
{
- rt_size_t loop_va = __UMASKVALUE((rt_size_t)v_addr, PAGE_OFFSET_MASK);
- rt_size_t loop_pa = __UMASKVALUE((rt_size_t)p_addr, PAGE_OFFSET_MASK);
-
- if (!mmu_info)
- {
- return -1;
- }
+ int ret = -1;
+ void *unmap_va = v_addr;
+ size_t npages = size >> ARCH_PAGE_SHIFT;
+ // TODO trying with HUGEPAGE here
while (npages--)
{
- if (_mmu_map_one_page(mmu_info, loop_va, loop_pa, attr) != 0)
+ ret = _map_one_page(aspace, v_addr, p_addr, attr);
+ if (ret != 0)
{
- __rt_hw_mmu_unmap(mmu_info, v_addr, npages);
- return -1;
+ /* error, undo map */
+ while (unmap_va != v_addr)
+ {
+ MM_PGTBL_LOCK(aspace);
+ _unmap_area(aspace, unmap_va, ARCH_PAGE_SIZE);
+ MM_PGTBL_UNLOCK(aspace);
+ unmap_va += ARCH_PAGE_SIZE;
+ }
+ break;
}
-
- loop_va += PAGE_SIZE;
- loop_pa += PAGE_SIZE;
+ v_addr += ARCH_PAGE_SIZE;
+ p_addr += ARCH_PAGE_SIZE;
}
- return 0;
-}
-
-void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, rt_size_t size, rt_size_t attr)
-{
- rt_size_t pa_s, pa_e;
- rt_size_t vaddr;
- rt_size_t pages;
- int ret;
-
- if (!size)
+ if (ret == 0)
{
- return 0;
+ return unmap_va;
}
- pa_s = (rt_size_t)p_addr;
- pa_e = ((rt_size_t)p_addr) + size - 1;
- pa_s = GET_PF_ID(pa_s);
- pa_e = GET_PF_ID(pa_e);
- pages = pa_e - pa_s + 1;
+ return NULL;
+}
- if (v_addr)
+static void _unmap_pte(rt_size_t *pentry, rt_size_t *lvl_entry[], int level)
+{
+ int loop_flag = 1;
+ while (loop_flag)
{
- vaddr = (rt_size_t)v_addr;
- pa_s = (rt_size_t)p_addr;
+ loop_flag = 0;
+ *pentry = 0;
+ rt_hw_cpu_dcache_clean(pentry, sizeof(*pentry));
- if (GET_PF_OFFSET(vaddr) != GET_PF_OFFSET(pa_s))
+ // we don't handle level 0, which is maintained by caller
+ if (level > 0)
{
- return 0;
- }
+ void *page = (void *)((rt_ubase_t)pentry & ~ARCH_PAGE_MASK);
- vaddr = __UMASKVALUE(vaddr, PAGE_OFFSET_MASK);
+ // decrease reference from child page to parent
+ rt_pages_free(page, 0);
- if (check_vaddr(mmu_info, (void *)vaddr, pages) != 0)
- {
- return 0;
- }
- }
- else
- {
- vaddr = find_vaddr(mmu_info, pages);
- }
-
- if (vaddr)
- {
- ret = __rt_hw_mmu_map(mmu_info, (void *)vaddr, p_addr, pages, attr);
-
- if (ret == 0)
- {
- rt_hw_cpu_tlb_invalidate();
- return (void *)(vaddr | GET_PF_OFFSET((rt_size_t)p_addr));
+ int free = rt_page_ref_get(page, 0);
+ if (free == 1)
+ {
+ rt_pages_free(page, 0);
+ pentry = lvl_entry[--level];
+ loop_flag = 1;
+ }
}
}
-
- return 0;
}
-static int __rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, rt_size_t npages, rt_size_t attr)
+static size_t _unmap_area(struct rt_aspace *aspace, void *v_addr, size_t size)
{
rt_size_t loop_va = __UMASKVALUE((rt_size_t)v_addr, PAGE_OFFSET_MASK);
- rt_size_t loop_pa;
- rt_size_t l1_off, l2_off, l3_off;
- rt_size_t *mmu_l1, *mmu_l2, *mmu_l3;
- rt_size_t *ref_cnt;
- rt_size_t i;
- void *va, *pa;
+ size_t unmapped = 0;
- if (!mmu_info)
+ int i = 0;
+ rt_size_t lvl_off[3];
+ rt_size_t *lvl_entry[3];
+ lvl_off[0] = (rt_size_t)GET_L1(loop_va);
+ lvl_off[1] = (rt_size_t)GET_L2(loop_va);
+ lvl_off[2] = (rt_size_t)GET_L3(loop_va);
+ unmapped = 1 << (ARCH_PAGE_SHIFT + ARCH_INDEX_WIDTH * 2ul);
+
+ rt_size_t *pentry;
+ lvl_entry[i] = ((rt_size_t *)aspace->page_table + lvl_off[i]);
+ pentry = lvl_entry[i];
+
+ // find leaf page table entry
+ while (PTE_USED(*pentry) && !PAGE_IS_LEAF(*pentry))
{
- return -1;
+ i += 1;
+ lvl_entry[i] = ((rt_size_t *)PPN_TO_VPN(GET_PADDR(*pentry), PV_OFFSET) +
+ lvl_off[i]);
+ pentry = lvl_entry[i];
+ unmapped >>= ARCH_INDEX_WIDTH;
}
- while (npages--)
+ // clear PTE & setup its
+ if (PTE_USED(*pentry))
{
- loop_pa = (rt_size_t)rt_pages_alloc(0);
-
- if (!loop_pa)
- {
- goto err;
- }
-
- if (__rt_hw_mmu_map(mmu_info, (void *)loop_va, (void *)loop_pa, 1, attr) < 0)
- {
- goto err;
- }
-
- loop_va += PAGE_SIZE;
+ _unmap_pte(pentry, lvl_entry, i);
}
- return 0;
+ return unmapped;
+}
-err:
- va = (void *)__UMASKVALUE((rt_size_t)v_addr, PAGE_OFFSET_MASK);
+/** unmap is different from map that it can handle multiple pages */
+void rt_hw_mmu_unmap(struct rt_aspace *aspace, void *v_addr, size_t size)
+{
+ // caller guarantee that v_addr & size are page aligned
+ if (!aspace->page_table)
+ {
+ return;
+ }
+ size_t unmapped = 0;
- for (i = 0; i < npages; i++)
+ while (size > 0)
{
- pa = rt_hw_mmu_v2p(mmu_info, va);
+ MM_PGTBL_LOCK(aspace);
+ unmapped = _unmap_area(aspace, v_addr, size);
+ MM_PGTBL_UNLOCK(aspace);
- if (pa)
- {
- rt_pages_free((void *)PPN_TO_VPN(pa, mmu_info->pv_off), 0);
- }
+ // when unmapped == 0, region not exist in pgtbl
+ if (!unmapped || unmapped > size)
+ break;
- va = (void *)((rt_uint8_t *)va + PAGE_SIZE);
+ size -= unmapped;
+ v_addr += unmapped;
}
+}
- __rt_hw_mmu_unmap(mmu_info, v_addr, npages);
- return -1;
+#ifdef RT_USING_SMART
+static inline void _init_region(void *vaddr, size_t size)
+{
+ rt_ioremap_start = vaddr;
+ rt_ioremap_size = size;
+ rt_mpr_start = rt_ioremap_start - rt_mpr_size;
+}
+#else
+static inline void _init_region(void *vaddr, size_t size)
+{
+ rt_mpr_start = vaddr - rt_mpr_size;
}
+#endif
-void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, rt_size_t size, rt_size_t attr)
+int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, rt_size_t size,
+ rt_size_t *vtable, rt_size_t pv_off)
{
- rt_size_t vaddr;
- rt_size_t offset;
- rt_size_t pages;
- int ret;
+ size_t l1_off, va_s, va_e;
+ rt_base_t level;
- if (!size)
+ if ((!aspace) || (!vtable))
{
- return 0;
+ return -1;
}
- offset = GET_PF_OFFSET((rt_size_t)v_addr);
- size += (offset + PAGE_SIZE - 1);
- pages = size >> PAGE_OFFSET_BIT;
+ va_s = (rt_size_t)v_address;
+ va_e = ((rt_size_t)v_address) + size - 1;
- if (v_addr)
+ if (va_e < va_s)
{
- vaddr = __UMASKVALUE((rt_size_t)v_addr, PAGE_OFFSET_MASK);
-
- if (check_vaddr(mmu_info, (void *)vaddr, pages) != 0)
- {
- return 0;
- }
+ return -1;
}
- else
+
+ // convert address to PPN2 index
+ va_s = GET_L1(va_s);
+ va_e = GET_L1(va_e);
+
+ if (va_s == 0)
{
- vaddr = find_vaddr(mmu_info, pages);
+ return -1;
}
- if (vaddr)
+ // vtable initialization check
+ for (l1_off = va_s; l1_off <= va_e; l1_off++)
{
- ret = __rt_hw_mmu_map_auto(mmu_info, (void *)vaddr, pages, attr);
+ size_t v = vtable[l1_off];
- if (ret == 0)
+ if (v)
{
- rt_hw_cpu_tlb_invalidate();
- return (void *)(vaddr | offset);
+ return -1;
}
}
- return 0;
-}
-
-void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, rt_size_t size)
-{
- rt_size_t va_s, va_e;
- rt_size_t pages;
-
- va_s = ((rt_size_t)v_addr) >> PAGE_OFFSET_BIT;
- va_e = (((rt_size_t)v_addr) + size - 1) >> PAGE_OFFSET_BIT;
- pages = va_e - va_s + 1;
- __rt_hw_mmu_unmap(mmu_info, v_addr, pages);
- rt_hw_cpu_tlb_invalidate();
-}
-
-void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, rt_size_t size, rt_size_t attr)
-{
- void *ret;
- rt_base_t level;
+ rt_aspace_init(&rt_kernel_space, (void *)0x1000, USER_VADDR_START - 0x1000,
+ vtable);
- rt_mm_lock();
- ret = _rt_hw_mmu_map(mmu_info, v_addr, p_addr, size, attr);
- rt_mm_unlock();
- return ret;
+ _init_region(v_address, size);
+ return 0;
}
-void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, rt_size_t size, rt_size_t attr)
-{
- void *ret;
- rt_base_t level;
-
- rt_mm_lock();
- ret = _rt_hw_mmu_map_auto(mmu_info, v_addr, size, attr);
- rt_mm_unlock();
- return ret;
-}
+const static int max_level =
+ (ARCH_VADDR_WIDTH - ARCH_PAGE_SHIFT) / ARCH_INDEX_WIDTH;
-void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, rt_size_t size)
+static inline uintptr_t _get_level_size(int level)
{
- rt_base_t level;
-
- rt_mm_lock();
- _rt_hw_mmu_unmap(mmu_info, v_addr, size);
- rt_mm_unlock();
+ return 1ul << (ARCH_PAGE_SHIFT + (max_level - level) * ARCH_INDEX_WIDTH);
}
-void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr)
+static rt_size_t *_query(struct rt_aspace *aspace, void *vaddr, int *level)
{
rt_size_t l1_off, l2_off, l3_off;
rt_size_t *mmu_l1, *mmu_l2, *mmu_l3;
rt_size_t pa;
- l1_off = GET_L1((rt_size_t)v_addr);
- l2_off = GET_L2((rt_size_t)v_addr);
- l3_off = GET_L3((rt_size_t)v_addr);
+ l1_off = GET_L1((rt_size_t)vaddr);
+ l2_off = GET_L2((rt_size_t)vaddr);
+ l3_off = GET_L3((rt_size_t)vaddr);
- if (!mmu_info)
+ if (!aspace)
{
+ LOG_W("%s: no aspace", __func__);
return RT_NULL;
}
- mmu_l1 = ((rt_size_t *)mmu_info->vtable) + l1_off;
+ mmu_l1 = ((rt_size_t *)aspace->page_table) + l1_off;
if (PTE_USED(*mmu_l1))
{
if (*mmu_l1 & PTE_XWR_MASK)
- return (void *)(GET_PADDR(*mmu_l1) | ((rt_size_t)v_addr & ((1 << 30) - 1)));
+ {
+ *level = 1;
+ return mmu_l1;
+ }
- mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1), mmu_info->pv_off);
+ mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1), PV_OFFSET);
if (PTE_USED(*(mmu_l2 + l2_off)))
{
if (*(mmu_l2 + l2_off) & PTE_XWR_MASK)
- return (void *)(GET_PADDR(*(mmu_l2 + l2_off)) | ((rt_size_t)v_addr & ((1 << 21) - 1)));
+ {
+ *level = 2;
+ return mmu_l2 + l2_off;
+ }
- mmu_l3 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*(mmu_l2 + l2_off)), mmu_info->pv_off);
+ mmu_l3 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*(mmu_l2 + l2_off)),
+ PV_OFFSET);
if (PTE_USED(*(mmu_l3 + l3_off)))
{
- return (void *)(GET_PADDR(*(mmu_l3 + l3_off)) | GET_PF_OFFSET((rt_size_t)v_addr));
+ *level = 3;
+ return mmu_l3 + l3_off;
}
}
}
@@ -592,15 +369,71 @@ void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr)
return RT_NULL;
}
-void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr)
+void *rt_hw_mmu_v2p(struct rt_aspace *aspace, void *vaddr)
{
- void *ret;
- rt_base_t level;
+ int level;
+ uintptr_t *pte = _query(aspace, vaddr, &level);
+ uintptr_t paddr;
+
+ if (pte)
+ {
+ paddr = GET_PADDR(*pte);
+ paddr |= ((intptr_t)vaddr & (_get_level_size(level) - 1));
+ }
+ else
+ {
+ paddr = (uintptr_t)ARCH_MAP_FAILED;
+ }
+ return (void *)paddr;
+}
+
+static int _noncache(uintptr_t *pte)
+{
+ return 0;
+}
+
+static int _cache(uintptr_t *pte)
+{
+ return 0;
+}
+
+static int (*control_handler[MMU_CNTL_DUMMY_END])(uintptr_t *pte) = {
+ [MMU_CNTL_CACHE] = _cache,
+ [MMU_CNTL_NONCACHE] = _noncache,
+};
+
+int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size,
+ enum rt_mmu_cntl cmd)
+{
+ int level;
+ int err = -RT_EINVAL;
+ void *vend = vaddr + size;
+
+ int (*handler)(uintptr_t * pte);
+ if (cmd >= 0 && cmd < MMU_CNTL_DUMMY_END)
+ {
+ handler = control_handler[cmd];
+
+ while (vaddr < vend)
+ {
+ uintptr_t *pte = _query(aspace, vaddr, &level);
+ void *range_end = vaddr + _get_level_size(level);
+ RT_ASSERT(range_end <= vend);
+
+ if (pte)
+ {
+ err = handler(pte);
+ RT_ASSERT(err == RT_EOK);
+ }
+ vaddr = range_end;
+ }
+ }
+ else
+ {
+ err = -RT_ENOSYS;
+ }
- rt_mm_lock();
- ret = _rt_hw_mmu_v2p(mmu_info, v_addr);
- rt_mm_unlock();
- return ret;
+ return err;
}
/**
@@ -615,7 +448,7 @@ void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr)
* @param mdesc
* @param desc_nr
*/
-void rt_hw_mmu_setup(rt_mmu_info *mmu_info, struct mem_desc *mdesc, int desc_nr)
+void rt_hw_mmu_setup(rt_aspace_t aspace, struct mem_desc *mdesc, int desc_nr)
{
void *err;
for (size_t i = 0; i < desc_nr; i++)
@@ -623,24 +456,31 @@ void rt_hw_mmu_setup(rt_mmu_info *mmu_info, struct mem_desc *mdesc, int desc_nr)
size_t attr;
switch (mdesc->attr)
{
- case NORMAL_MEM:
- attr = MMU_MAP_K_RWCB;
- break;
- case NORMAL_NOCACHE_MEM:
- attr = MMU_MAP_K_RWCB;
- break;
- case DEVICE_MEM:
- attr = MMU_MAP_K_DEVICE;
- break;
- default:
- attr = MMU_MAP_K_DEVICE;
+ case NORMAL_MEM:
+ attr = MMU_MAP_K_RWCB;
+ break;
+ case NORMAL_NOCACHE_MEM:
+ attr = MMU_MAP_K_RWCB;
+ break;
+ case DEVICE_MEM:
+ attr = MMU_MAP_K_DEVICE;
+ break;
+ default:
+ attr = MMU_MAP_K_DEVICE;
}
- err = _rt_hw_mmu_map(mmu_info, (void *)mdesc->vaddr_start, (void *)mdesc->paddr_start,
- mdesc->vaddr_end - mdesc->vaddr_start + 1, attr);
+
+ struct rt_mm_va_hint hint = {.flags = MMF_MAP_FIXED,
+ .limit_start = aspace->start,
+ .limit_range_size = aspace->size,
+ .map_size = mdesc->vaddr_end -
+ mdesc->vaddr_start + 1,
+ .prefer = (void *)mdesc->vaddr_start};
+
+ rt_aspace_map_phy_static(aspace, &mdesc->varea, &hint, attr,
+ mdesc->paddr_start >> MM_PAGE_SHIFT, &err);
mdesc++;
}
- rt_hw_mmu_switch((void *)MMUTable);
+ rt_hw_aspace_switch(&rt_kernel_space);
+ rt_page_cleanup();
}
-
-#endif /* RT_USING_SMART */
diff --git a/libcpu/risc-v/virt64/mmu.h b/libcpu/risc-v/virt64/mmu.h
index 086ad1edb9..ece5c1ccac 100644
--- a/libcpu/risc-v/virt64/mmu.h
+++ b/libcpu/risc-v/virt64/mmu.h
@@ -13,13 +13,17 @@
#include "riscv.h"
#include "riscv_mmu.h"
+#include <mm_aspace.h>
+#include <stddef.h>
/* RAM, Flash, or ROM */
-#define NORMAL_MEM 0
+#define NORMAL_MEM 0
/* normal nocache memory mapping type */
-#define NORMAL_NOCACHE_MEM 1
+#define NORMAL_NOCACHE_MEM 1
/* MMIO region */
-#define DEVICE_MEM 2
+#define DEVICE_MEM 2
+
+typedef size_t rt_pte_t;
struct mem_desc
{
@@ -27,48 +31,58 @@ struct mem_desc
rt_size_t vaddr_end;
rt_size_t paddr_start;
rt_size_t attr;
+ struct rt_varea varea;
};
-#define GET_PF_ID(addr) ((addr) >> PAGE_OFFSET_BIT)
+#define GET_PF_ID(addr) ((addr) >> PAGE_OFFSET_BIT)
#define GET_PF_OFFSET(addr) __MASKVALUE(addr, PAGE_OFFSET_MASK)
-#define GET_L1(addr) __PARTBIT(addr, VPN2_SHIFT, VPN2_BIT)
-#define GET_L2(addr) __PARTBIT(addr, VPN1_SHIFT, VPN1_BIT)
-#define GET_L3(addr) __PARTBIT(addr, VPN0_SHIFT, VPN0_BIT)
-#define GET_PPN(pte) (__PARTBIT(pte, PTE_PPN_SHIFT, PHYSICAL_ADDRESS_WIDTH_BITS - PTE_PPN_SHIFT))
-#define GET_PADDR(pte) (GET_PPN(pte) << PAGE_OFFSET_BIT)
+#define GET_L1(addr) __PARTBIT(addr, VPN2_SHIFT, VPN2_BIT)
+#define GET_L2(addr) __PARTBIT(addr, VPN1_SHIFT, VPN1_BIT)
+#define GET_L3(addr) __PARTBIT(addr, VPN0_SHIFT, VPN0_BIT)
+#define GET_PPN(pte) \
+ (__PARTBIT(pte, PTE_PPN_SHIFT, PHYSICAL_ADDRESS_WIDTH_BITS - PTE_PPN_SHIFT))
+#define GET_PADDR(pte) (GET_PPN(pte) << PAGE_OFFSET_BIT)
#define VPN_TO_PPN(vaddr, pv_off) (((rt_size_t)(vaddr)) + (pv_off))
#define PPN_TO_VPN(paddr, pv_off) (((rt_size_t)(paddr)) - (pv_off))
-#define COMBINEVADDR(l1_off, l2_off, l3_off) (((l1_off) << VPN2_SHIFT) | ((l2_off) << VPN1_SHIFT) | ((l3_off) << VPN0_SHIFT))
-#define COMBINEPTE(paddr, attr) ((((paddr) >> PAGE_OFFSET_BIT) << PTE_PPN_SHIFT) | (attr))
+#define COMBINEVADDR(l1_off, l2_off, l3_off) \
+ (((l1_off) << VPN2_SHIFT) | ((l2_off) << VPN1_SHIFT) | \
+ ((l3_off) << VPN0_SHIFT))
+#define COMBINEPTE(paddr, attr) \
+ ((((paddr) >> PAGE_OFFSET_BIT) << PTE_PPN_SHIFT) | (attr))
-typedef struct
-{
- size_t *vtable;
- size_t vstart;
- size_t vend;
- size_t pv_off;
-} rt_mmu_info;
+#define ARCH_ADDRESS_WIDTH_BITS 64
+
+#define MMU_MAP_ERROR_VANOTALIGN -1
+#define MMU_MAP_ERROR_PANOTALIGN -2
+#define MMU_MAP_ERROR_NOPAGE -3
+#define MMU_MAP_ERROR_CONFLICT -4
void *rt_hw_mmu_tbl_get();
-void rt_hw_mmu_switch(void *mmu_table);
-int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void *v_address, rt_size_t size, rt_size_t *vtable, rt_size_t pv_off);
-void rt_hw_mmu_kernel_map_init(rt_mmu_info *mmu_info, rt_size_t vaddr_start, rt_size_t size);
-void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, rt_size_t size, rt_size_t attr);
-void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, rt_size_t size, rt_size_t attr);
-void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, rt_size_t size);
-void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, rt_size_t size, rt_size_t attr);
-void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, rt_size_t size, rt_size_t attr);
-void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, rt_size_t size);
-void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr);
-void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr);
+int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, rt_size_t size,
+ rt_size_t *vtable, rt_size_t pv_off);
+void rt_hw_mmu_setup(rt_aspace_t aspace, struct mem_desc *mdesc, int desc_nr);
+void rt_hw_mmu_kernel_map_init(rt_aspace_t aspace, rt_size_t vaddr_start,
+ rt_size_t size);
+void *rt_hw_mmu_map(rt_aspace_t aspace, void *v_addr, void *p_addr, size_t size,
+ size_t attr);
+void rt_hw_mmu_unmap(rt_aspace_t aspace, void *v_addr, size_t size);
+void rt_hw_aspace_switch(rt_aspace_t aspace);
+void *rt_hw_mmu_v2p(rt_aspace_t aspace, void *vaddr);
-void rt_hw_mmu_setup(rt_mmu_info *mmu_info, struct mem_desc *mdesc, int desc_nr);
+static inline void *_rt_kmem_v2p(void *vaddr)
+{
+ return rt_hw_mmu_v2p(&rt_kernel_space, vaddr);
+}
-#define ARCH_ADDRESS_WIDTH_BITS 64
+static inline void *rt_kmem_v2p(void *vaddr)
+{
+ MM_PGTBL_LOCK(&rt_kernel_space);
+ void *paddr = _rt_kmem_v2p(vaddr);
+ MM_PGTBL_UNLOCK(&rt_kernel_space);
+ return paddr;
+}
-#define MMU_MAP_ERROR_VANOTALIGN -1
-#define MMU_MAP_ERROR_PANOTALIGN -2
-#define MMU_MAP_ERROR_NOPAGE -3
-#define MMU_MAP_ERROR_CONFLICT -4
+int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size,
+ enum rt_mmu_cntl cmd);
#endif
diff --git a/libcpu/risc-v/virt64/riscv_mmu.c b/libcpu/risc-v/virt64/riscv_mmu.c
index e79ca8b37b..7c4f886345 100644
--- a/libcpu/risc-v/virt64/riscv_mmu.c
+++ b/libcpu/risc-v/virt64/riscv_mmu.c
@@ -11,23 +11,13 @@
#include <rthw.h>
#include <rtthread.h>
-#include <stdint.h>
#include <riscv.h>
-#include <string.h>
+#include <stdint.h>
#include <stdlib.h>
+#include <string.h>
#include "riscv_mmu.h"
-void mmu_set_pagetable(rt_ubase_t addr)
-{
- RT_ASSERT(__CHECKALIGN(addr, PAGE_OFFSET_BIT));
- RT_ASSERT(__CHECKUPBOUND(addr, PHYSICAL_ADDRESS_WIDTH_BITS));
-
- mmu_flush_tlb();
- write_csr(satp, (((size_t)SATP_MODE) << SATP_MODE_OFFSET) | (addr >> PAGE_OFFSET_BIT));
- mmu_flush_tlb();
-}
-
void mmu_enable_user_page_access()
{
set_csr(sstatus, SSTATUS_SUM);
diff --git a/libcpu/risc-v/virt64/riscv_mmu.h b/libcpu/risc-v/virt64/riscv_mmu.h
index 04c4201aab..fc5a143b65 100644
--- a/libcpu/risc-v/virt64/riscv_mmu.h
+++ b/libcpu/risc-v/virt64/riscv_mmu.h
@@ -58,7 +58,7 @@
#define PTE_USED(pte) __MASKVALUE(pte, PTE_V)
-/**
+/**
* encoding of SATP (Supervisor Address Translation and Protection register)
*/
#define SATP_MODE_OFFSET 60
@@ -68,16 +68,9 @@
#define SATP_MODE_SV57 10
#define SATP_MODE_SV64 11
-#define ARCH_VA_WIDTH 39
+#define ARCH_VADDR_WIDTH 39
#define SATP_MODE SATP_MODE_SV39
-#define mmu_flush_tlb() \
- do \
- { \
- asm volatile("sfence.vma x0,x0"); \
- } while (0)
-
-
#define MMU_MAP_K_DEVICE (PTE_G | PTE_W | PTE_R | PTE_V)
#define MMU_MAP_K_RWCB (PTE_G | PTE_X | PTE_W | PTE_R | PTE_V)
#define MMU_MAP_U_RWCB (PTE_U | PTE_X | PTE_W | PTE_R | PTE_V)
@@ -93,6 +86,8 @@
#define ARCH_INDEX_SIZE (1ul << ARCH_INDEX_WIDTH)
#define ARCH_INDEX_MASK (ARCH_INDEX_SIZE - 1)
+#define ARCH_MAP_FAILED ((void *)0x8000000000000000)
+
void mmu_set_pagetable(rt_ubase_t addr);
void mmu_enable_user_page_access();
void mmu_disable_user_page_access();
diff --git a/libcpu/risc-v/virt64/sbi.c b/libcpu/risc-v/virt64/sbi.c
index 93084bd441..b2b1e8e788 100644
--- a/libcpu/risc-v/virt64/sbi.c
+++ b/libcpu/risc-v/virt64/sbi.c
@@ -36,8 +36,8 @@
*/
#include "sbi.h"
-#include <stdbool.h>
#include <rtthread.h>
+#include <stdbool.h>
/* SBI Implementation-Specific Definitions */
#define OPENSBI_VERSION_MAJOR_OFFSET 16
@@ -51,20 +51,17 @@ static bool has_time_extension = false;
static bool has_ipi_extension = false;
static bool has_rfnc_extension = false;
-static struct sbi_ret
-sbi_get_spec_version(void)
+static struct sbi_ret sbi_get_spec_version(void)
{
return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_SPEC_VERSION));
}
-static struct sbi_ret
-sbi_get_impl_id(void)
+static struct sbi_ret sbi_get_impl_id(void)
{
return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_IMPL_ID));
}
-static struct sbi_ret
-sbi_get_impl_version(void)
+static struct sbi_ret sbi_get_impl_version(void)
{
return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_IMPL_VERSION));
}
@@ -88,7 +85,8 @@ void sbi_print_version(void)
rt_kprintf("SBI: Berkely Boot Loader %lu\n", sbi_impl_version);
break;
case (SBI_IMPL_ID_XVISOR):
- rt_kprintf("SBI: eXtensible Versatile hypervISOR %lu\n", sbi_impl_version);
+ rt_kprintf("SBI: eXtensible Versatile hypervISOR %lu\n",
+ sbi_impl_version);
break;
case (SBI_IMPL_ID_KVM):
rt_kprintf("SBI: Kernel-based Virtual Machine %lu\n", sbi_impl_version);
@@ -138,8 +136,7 @@ void sbi_send_ipi(const unsigned long *hart_mask)
/* Use the IPI legacy replacement extension, if available. */
if (has_ipi_extension)
{
- ret = SBI_CALL2(SBI_EXT_ID_IPI, SBI_IPI_SEND_IPI,
- *hart_mask, 0);
+ ret = SBI_CALL2(SBI_EXT_ID_IPI, SBI_IPI_SEND_IPI, *hart_mask, 0);
RT_ASSERT(ret.error == SBI_SUCCESS);
}
else
@@ -155,8 +152,8 @@ void sbi_remote_fence_i(const unsigned long *hart_mask)
/* Use the RFENCE legacy replacement extension, if available. */
if (has_rfnc_extension)
{
- ret = SBI_CALL2(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_FENCE_I,
- *hart_mask, 0);
+ ret =
+ SBI_CALL2(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_FENCE_I, *hart_mask, 0);
RT_ASSERT(ret.error == SBI_SUCCESS);
}
else
@@ -165,25 +162,28 @@ void sbi_remote_fence_i(const unsigned long *hart_mask)
}
}
-void sbi_remote_sfence_vma(const unsigned long *hart_mask, unsigned long start, unsigned long size)
+int sbi_remote_sfence_vma(const unsigned long *hart_mask,
+ const unsigned long hart_mask_base,
+ unsigned long start, unsigned long size)
{
- struct sbi_ret ret;
+ struct sbi_ret ret = {.error = SBI_SUCCESS};
/* Use the RFENCE legacy replacement extension, if available. */
if (has_rfnc_extension)
{
- ret = SBI_CALL4(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_SFENCE_VMA,
- *hart_mask, 0, start, size);
- RT_ASSERT(ret.error == SBI_SUCCESS);
+ ret = SBI_CALL4(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_SFENCE_VMA, *hart_mask,
+ hart_mask_base, start, size);
}
else
{
- (void)SBI_CALL3(SBI_REMOTE_SFENCE_VMA, 0, (uint64_t)hart_mask,
- start, size);
+ (void)SBI_CALL3(SBI_REMOTE_SFENCE_VMA, 0, (uint64_t)hart_mask, start,
+ size);
}
+ return ret.error;
}
-void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long start, unsigned long size,
+void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
+ unsigned long start, unsigned long size,
unsigned long asid)
{
struct sbi_ret ret;
@@ -197,12 +197,13 @@ void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long st
}
else
{
- (void)SBI_CALL4(SBI_REMOTE_SFENCE_VMA_ASID, 0,
- (uint64_t)hart_mask, start, size, asid);
+ (void)SBI_CALL4(SBI_REMOTE_SFENCE_VMA_ASID, 0, (uint64_t)hart_mask,
+ start, size, asid);
}
}
-int sbi_hsm_hart_start(unsigned long hart, unsigned long start_addr, unsigned long priv)
+int sbi_hsm_hart_start(unsigned long hart, unsigned long start_addr,
+ unsigned long priv)
{
struct sbi_ret ret;
diff --git a/libcpu/risc-v/virt64/sbi.h b/libcpu/risc-v/virt64/sbi.h
index a5ab83d27d..be54dede72 100644
--- a/libcpu/risc-v/virt64/sbi.h
+++ b/libcpu/risc-v/virt64/sbi.h
@@ -185,7 +185,9 @@ void sbi_send_ipi(const unsigned long *hart_mask);
/* RFENCE extension functions. */
void sbi_remote_fence_i(const unsigned long *hart_mask);
-void sbi_remote_sfence_vma(const unsigned long *hart_mask, unsigned long start, unsigned long size);
+int sbi_remote_sfence_vma(const unsigned long *hart_mask,
+ const unsigned long hart_mask_base,
+ unsigned long start, unsigned long size);
void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long start,
unsigned long size, unsigned long asid);
diff --git a/libcpu/risc-v/virt64/start.c b/libcpu/risc-v/virt64/start.c
new file mode 100644
index 0000000000..a8c374f698
--- /dev/null
+++ b/libcpu/risc-v/virt64/start.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-12-07 RT-Thread the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "board.h"
+
+void init_bss(void)
+{
+ unsigned int *dst;
+
+ dst = &__bss_start;
+ while (dst < &__bss_end)
+ {
+ *dst++ = 0;
+ }
+}
diff --git a/libcpu/risc-v/virt64/startup_gcc.S b/libcpu/risc-v/virt64/startup_gcc.S
index 700f31181d..c9ce4bcf1e 100644
--- a/libcpu/risc-v/virt64/startup_gcc.S
+++ b/libcpu/risc-v/virt64/startup_gcc.S
@@ -10,7 +10,7 @@
* 2020/6/12 Xim Port to QEMU and remove SMP support
*/
-#define SSTATUS_FS 0x00006000U /* initial state of FPU, clear to disable */
+#include <encoding.h>
#include <cpuport.h>
boot_hartid: .int
@@ -72,7 +72,7 @@ _start:
li x31,0
/* set to disable FPU */
- li t0, SSTATUS_FS
+ li t0, SSTATUS_FS + SSTATUS_VS
csrc sstatus, t0
li t0, 0x40000 // SUM in sstatus
csrs sstatus, t0
@@ -91,4 +91,6 @@ _start:
* sscratch is always zero on kernel mode
*/
csrw sscratch, zero
+ call init_bss
+ call sbi_init
j primary_cpu_entry
diff --git a/libcpu/risc-v/virt64/syscall_c.c b/libcpu/risc-v/virt64/syscall_c.c
index 9a946d98b9..8bda3e6278 100644
--- a/libcpu/risc-v/virt64/syscall_c.c
+++ b/libcpu/risc-v/virt64/syscall_c.c
@@ -21,7 +21,6 @@
#include <stdint.h>
#include <mmu.h>
#include <page.h>
-#include <lwp_mm_area.h>
#include <lwp_user_mm.h>
#include "riscv_mmu.h"
diff --git a/libcpu/risc-v/virt64/tlb.h b/libcpu/risc-v/virt64/tlb.h
new file mode 100644
index 0000000000..5bdf18c189
--- /dev/null
+++ b/libcpu/risc-v/virt64/tlb.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-11-28 WangXiaoyao the first version
+ */
+#ifndef __TLB_H__
+#define __TLB_H__
+
+#include "mm_aspace.h"
+#include "riscv_mmu.h"
+#include "rtdbg.h"
+#include "rtthread.h"
+#include <sbi.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#define HANDLE_FAULT(ret) \
+ if (__builtin_expect((ret) != SBI_SUCCESS, 0)) \
+ LOG_W("%s failed", __FUNCTION__);
+
+static inline void rt_hw_tlb_invalidate_all(void)
+{
+ uintptr_t mask = -1ul;
+ HANDLE_FAULT(sbi_remote_sfence_vma(&mask, -1ul, 0, mask));
+}
+
+static inline void rt_hw_tlb_invalidate_all_local(void)
+{
+ __asm__ volatile("sfence.vma" ::: "memory");
+}
+
+static inline void rt_hw_tlb_invalidate_aspace(rt_aspace_t aspace)
+{
+ // TODO ASID
+ rt_hw_tlb_invalidate_all_local();
+}
+
+static inline void rt_hw_tlb_invalidate_page(rt_aspace_t aspace, void *start)
+{
+ __asm__ volatile("sfence.vma %0, zero" ::"r"(start) : "memory");
+}
+
+static inline void rt_hw_tlb_invalidate_range(rt_aspace_t aspace, void *start,
+ size_t size, size_t stride)
+{
+ // huge page is taking as normal page
+ if (size <= ARCH_PAGE_SIZE)
+ {
+ rt_hw_tlb_invalidate_page(aspace, start);
+ }
+ else
+ {
+ rt_hw_tlb_invalidate_aspace(aspace);
+ }
+}
+
+#endif /* __TLB_H__ */
diff --git a/libcpu/risc-v/virt64/trap.c b/libcpu/risc-v/virt64/trap.c
index 0a5c082f30..07d9894f4a 100644
--- a/libcpu/risc-v/virt64/trap.c
+++ b/libcpu/risc-v/virt64/trap.c
@@ -12,6 +12,7 @@
#include <stdint.h>
#include "encoding.h"
+#include "mm_fault.h"
#include "stack.h"
#include "sbi.h"
#include "riscv.h"
@@ -139,7 +140,17 @@ extern struct rt_irq_desc irq_desc[];
#include "rtdbg.h"
#include "encoding.h"
-void sys_exit(int value);
+
+#ifndef RT_USING_SMP
+static volatile int nested = 0;
+#define ENTER_TRAP \
+ nested += 1
+#define EXIT_TRAP \
+ nested -= 1
+#define CHECK_NESTED_PANIC(cause, tval, epc, eframe) \
+ if (nested != 1) \
+ handle_nested_trap_panic(cause, tval, epc, eframe)
+#endif /* RT_USING_SMP */
static const char *get_exception_msg(int id)
{
@@ -161,10 +172,59 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw
rt_size_t id = __MASKVALUE(scause, __MASK(63UL));
/* user page fault */
- if (id == EP_LOAD_PAGE_FAULT ||
- id == EP_STORE_PAGE_FAULT)
+ enum rt_mm_fault_op fault_op;
+ enum rt_mm_fault_type fault_type;
+ switch (id)
+ {
+ case EP_LOAD_PAGE_FAULT:
+ fault_op = MM_FAULT_OP_READ;
+ fault_type = MM_FAULT_TYPE_PAGE_FAULT;
+ break;
+ case EP_LOAD_ACCESS_FAULT:
+ fault_op = MM_FAULT_OP_READ;
+ fault_type = MM_FAULT_TYPE_ACCESS_FAULT;
+ break;
+ case EP_LOAD_ADDRESS_MISALIGNED:
+ fault_op = MM_FAULT_OP_READ;
+ fault_type = MM_FAULT_TYPE_BUS_ERROR;
+ break;
+ case EP_STORE_PAGE_FAULT:
+ fault_op = MM_FAULT_OP_WRITE;
+ fault_type = MM_FAULT_TYPE_PAGE_FAULT;
+ break;
+ case EP_STORE_ACCESS_FAULT:
+ fault_op = MM_FAULT_OP_WRITE;
+ fault_type = MM_FAULT_TYPE_ACCESS_FAULT;
+ break;
+ case EP_STORE_ADDRESS_MISALIGNED:
+ fault_op = MM_FAULT_OP_WRITE;
+ fault_type = MM_FAULT_TYPE_BUS_ERROR;
+ break;
+ case EP_INSTRUCTION_PAGE_FAULT:
+ fault_op = MM_FAULT_OP_EXECUTE;
+ fault_type = MM_FAULT_TYPE_PAGE_FAULT;
+ break;
+ case EP_INSTRUCTION_ACCESS_FAULT:
+ fault_op = MM_FAULT_OP_EXECUTE;
+ fault_type = MM_FAULT_TYPE_ACCESS_FAULT;
+ break;
+ case EP_INSTRUCTION_ADDRESS_MISALIGNED:
+ fault_op = MM_FAULT_OP_EXECUTE;
+ fault_type = MM_FAULT_TYPE_BUS_ERROR;
+ break;
+ default:
+ fault_op = 0;
+ }
+
+ if (fault_op)
{
- if (arch_expand_user_stack((void *)stval))
+ struct rt_mm_fault_msg msg = {
+ .fault_op = fault_op,
+ .fault_type = fault_type,
+ .vaddr = (void *)stval,
+ };
+
+ if (rt_mm_fault_try_fix(&msg))
{
return;
}
@@ -176,6 +236,8 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw
rt_hw_backtrace((uint32_t *)sp->s0_fp, sepc);
LOG_E("User Fault, killing thread: %s", rt_thread_self()->name);
+
+ EXIT_TRAP;
sys_exit(-1);
}
#endif
@@ -228,17 +290,6 @@ static void handle_nested_trap_panic(
rt_hw_cpu_shutdown();
}
-#ifndef RT_USING_SMP
-static volatile int nested = 0;
-#define ENTER_TRAP \
- nested += 1
-#define EXIT_TRAP \
- nested -= 1
-#define CHECK_NESTED_PANIC(cause, tval, epc, eframe) \
- if (nested != 1) \
- handle_nested_trap_panic(cause, tval, epc, eframe)
-#endif /* RT_USING_SMP */
-
/* Trap entry */
void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw_stack_frame *sp)
{
diff --git a/src/Kconfig b/src/Kconfig
index 1711b67bc3..ee6f6643ee 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -303,6 +303,16 @@ endmenu
menu "Memory Management"
+ config RT_PAGE_MAX_ORDER
+ int "Max order of pages allocatable by page allocator"
+ default 11
+ help
+ For example, A value of 11 means the maximum chunk of contiguous memory
+ allocatable by page system is 2^(11 + ARCH_PAGE_BITS - 1) Bytes.
+ Large memory requirement can consume all system resource, and should
+ consider reserved memory instead to enhance system endurance.
+ Max order should at least satisfied usage by huge page.
+
config RT_USING_MEMPOOL
bool "Using memory pool"
default y
diff --git a/src/cpu.c b/src/cpu.c
index ada3464a1d..79a820d39e 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -247,7 +247,7 @@ void rt_cpus_lock_status_restore(struct rt_thread *thread)
struct rt_cpu* pcpu = rt_cpu_self();
#if defined(ARCH_MM_MMU) && defined(RT_USING_SMART)
- lwp_mmu_switch(thread);
+ lwp_aspace_switch(thread);
#endif
pcpu->current_thread = thread;
if (!thread->cpus_lock_nest)