From 7450ef6c4d71f992444d27f4a26c16f813ed8e55 Mon Sep 17 00:00:00 2001 From: Shell Date: Mon, 9 Jan 2023 10:08:55 +0800 Subject: [PATCH] [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 --- bsp/allwinner/d1s/.config | 169 ++- bsp/allwinner/d1s/board/board.c | 13 +- bsp/allwinner/d1s/board/board.h | 1 + bsp/allwinner/d1s/link.lds | 20 +- bsp/allwinner/d1s/rtconfig.h | 31 +- bsp/allwinner/d1s/rtconfig.py | 4 +- bsp/qemu-vexpress-a9/.config | 796 +----------- bsp/qemu-vexpress-a9/drivers/board.c | 19 +- bsp/qemu-vexpress-a9/drivers/board.h | 2 - bsp/qemu-vexpress-a9/qemu-dbg.sh | 2 +- bsp/qemu-vexpress-a9/rtconfig.h | 126 +- bsp/qemu-vexpress-a9/rtconfig.py | 2 +- bsp/qemu-virt64-aarch64/.config | 627 +-------- bsp/qemu-virt64-aarch64/drivers/board.c | 36 +- bsp/qemu-virt64-aarch64/drivers/virt.h | 1 - bsp/qemu-virt64-aarch64/qemu-debug.sh | 2 +- bsp/qemu-virt64-aarch64/qemu.sh | 2 +- bsp/qemu-virt64-aarch64/rtconfig.h | 109 +- bsp/qemu-virt64-riscv/.config | 639 +--------- .../applications/test/test_mm/SConscript | 9 - .../applications/test/test_mm/test_mm.c | 118 -- bsp/qemu-virt64-riscv/driver/board.c | 30 +- bsp/qemu-virt64-riscv/driver/board.h | 13 +- bsp/qemu-virt64-riscv/driver/virt.h | 1 - bsp/qemu-virt64-riscv/qemu-dbg.sh | 1 + bsp/qemu-virt64-riscv/qemu-v-dbg.sh | 3 +- bsp/qemu-virt64-riscv/rtconfig.h | 113 +- bsp/raspberry-pi/raspi3-64/.config | 1 + bsp/raspberry-pi/raspi3-64/driver/board.c | 5 +- bsp/raspberry-pi/raspi3-64/rtconfig.h | 1 + bsp/raspberry-pi/raspi4-32/.config | 193 +-- bsp/raspberry-pi/raspi4-32/rtconfig.h | 19 +- bsp/raspberry-pi/raspi4-64/.config | 193 +-- bsp/raspberry-pi/raspi4-64/driver/board.c | 5 +- bsp/raspberry-pi/raspi4-64/rtconfig.h | 19 +- bsp/rockchip/rk3568/.config | 191 +-- bsp/rockchip/rk3568/driver/board.c | 5 +- bsp/rockchip/rk3568/rtconfig.h | 19 +- components/drivers/virtio/virtio.h | 3 +- .../lwp/arch/aarch64/cortex-a/lwp_arch.c | 34 +- components/lwp/arch/arm/common/reloc.c | 11 +- components/lwp/arch/arm/cortex-a/lwp_arch.c | 50 +- components/lwp/arch/risc-v/rv64/lwp_arch.c | 55 +- components/lwp/arch/risc-v/rv64/lwp_arch.h | 9 +- components/lwp/arch/risc-v/rv64/reloc.c | 11 +- components/lwp/ioremap.c | 72 +- components/lwp/ioremap.h | 5 + components/lwp/lwp.c | 18 +- components/lwp/lwp.h | 13 +- components/lwp/lwp_arch_comm.h | 8 +- components/lwp/lwp_mm_area.c | 122 -- components/lwp/lwp_mm_area.h | 53 - components/lwp/lwp_shm.c | 73 +- components/lwp/lwp_syscall.c | 32 +- components/lwp/lwp_user_mm.c | 523 ++++---- components/lwp/lwp_user_mm.h | 33 +- components/lwp/page.c | 424 ------- components/lwp/page.h | 28 +- components/mm/SConscript | 21 + components/mm/avl_adpt.c | 178 +++ components/mm/avl_adpt.h | 37 + components/mm/mm_aspace.c | 743 +++++++++++ components/mm/mm_aspace.h | 202 +++ components/mm/mm_fault.c | 135 ++ components/mm/mm_fault.h | 55 + components/mm/mm_flag.h | 89 ++ components/mm/mm_object.c | 109 ++ components/mm/mm_page.c | 644 ++++++++++ components/mm/mm_page.h | 81 ++ components/mm/mm_private.h | 94 ++ components/utilities/libadt/SConscript | 8 + components/utilities/libadt/avl.c | 231 ++++ components/utilities/libadt/avl.h | 116 ++ include/rtdef.h | 4 +- include/rthw.h | 5 + libcpu/aarch64/common/context_gcc.S | 27 +- libcpu/aarch64/common/cpu_ops_common.h | 2 +- libcpu/aarch64/common/cpuport.h | 15 +- libcpu/aarch64/common/interrupt.c | 14 +- libcpu/aarch64/common/mmu.c | 1118 ++++++----------- libcpu/aarch64/common/mmu.h | 133 +- libcpu/aarch64/common/tlb.h | 80 ++ libcpu/aarch64/common/trap.c | 49 +- libcpu/aarch64/cortex-a/entry_point.S | 19 +- libcpu/arm/cortex-a/context_gcc.S | 4 +- libcpu/arm/cortex-a/cpuport.h | 2 + libcpu/arm/cortex-a/interrupt.c | 7 +- libcpu/arm/cortex-a/mmu.c | 749 +++-------- libcpu/arm/cortex-a/mmu.h | 51 +- libcpu/arm/cortex-a/start_gcc.S | 25 +- libcpu/arm/cortex-a/tlb.h | 48 + libcpu/arm/cortex-a/trap.c | 28 +- libcpu/risc-v/t-head/c906/backtrace.c | 137 ++ libcpu/risc-v/t-head/c906/context_gcc.S | 4 +- libcpu/risc-v/t-head/c906/cpuport.c | 7 +- libcpu/risc-v/t-head/c906/cpuport.h | 8 +- libcpu/risc-v/t-head/c906/encoding.h | 2 +- libcpu/risc-v/t-head/c906/interrupt_gcc.S | 2 +- libcpu/risc-v/t-head/c906/mmu.c | 972 +++++++------- libcpu/risc-v/t-head/c906/mmu.h | 96 +- libcpu/risc-v/t-head/c906/riscv_mmu.c | 12 +- libcpu/risc-v/t-head/c906/riscv_mmu.h | 45 +- libcpu/risc-v/t-head/c906/sbi.c | 85 +- libcpu/risc-v/t-head/c906/sbi.h | 6 +- libcpu/risc-v/t-head/c906/tlb.h | 61 + libcpu/risc-v/t-head/c906/trap.c | 77 +- libcpu/risc-v/virt64/backtrace.c | 7 +- libcpu/risc-v/virt64/context_gcc.S | 4 +- libcpu/risc-v/virt64/mmu.c | 870 ++++++------- libcpu/risc-v/virt64/mmu.h | 90 +- libcpu/risc-v/virt64/riscv_mmu.c | 14 +- libcpu/risc-v/virt64/riscv_mmu.h | 13 +- libcpu/risc-v/virt64/sbi.c | 47 +- libcpu/risc-v/virt64/sbi.h | 4 +- libcpu/risc-v/virt64/start.c | 24 + libcpu/risc-v/virt64/startup_gcc.S | 6 +- libcpu/risc-v/virt64/syscall_c.c | 1 - libcpu/risc-v/virt64/tlb.h | 61 + libcpu/risc-v/virt64/trap.c | 81 +- src/Kconfig | 10 + src/cpu.c | 2 +- 121 files changed, 5947 insertions(+), 7041 deletions(-) delete mode 100644 bsp/qemu-virt64-riscv/applications/test/test_mm/SConscript delete mode 100644 bsp/qemu-virt64-riscv/applications/test/test_mm/test_mm.c delete mode 100644 components/lwp/lwp_mm_area.c delete mode 100644 components/lwp/lwp_mm_area.h delete mode 100644 components/lwp/page.c create mode 100644 components/mm/SConscript create mode 100644 components/mm/avl_adpt.c create mode 100644 components/mm/avl_adpt.h create mode 100644 components/mm/mm_aspace.c create mode 100644 components/mm/mm_aspace.h create mode 100644 components/mm/mm_fault.c create mode 100644 components/mm/mm_fault.h create mode 100644 components/mm/mm_flag.h create mode 100644 components/mm/mm_object.c create mode 100644 components/mm/mm_page.c create mode 100644 components/mm/mm_page.h create mode 100644 components/mm/mm_private.h create mode 100644 components/utilities/libadt/SConscript create mode 100644 components/utilities/libadt/avl.c create mode 100644 components/utilities/libadt/avl.h create mode 100644 libcpu/aarch64/common/tlb.h create mode 100644 libcpu/arm/cortex-a/tlb.h create mode 100644 libcpu/risc-v/t-head/c906/backtrace.c create mode 100644 libcpu/risc-v/t-head/c906/tlb.h create mode 100644 libcpu/risc-v/virt64/start.c create mode 100644 libcpu/risc-v/virt64/tlb.h 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_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_SEEED_LIS3DHTR is not set -# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# 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 # -# Display libraries +# 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 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 #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 #include 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 @@ -295,797 +294,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 # 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 #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 #include #include #ifdef RT_USING_SMART -#include #include #endif #include "board.h" +#include #include #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 #include -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 @@ -352,646 +352,21 @@ 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 -#include - -#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 #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 - 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); + /* 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); + + /* 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 #include -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 @@ -814,12 +748,6 @@ CONFIG_RT_LWIP_USING_PING=y # 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 # @@ -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 @@ -800,12 +734,6 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y # 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 # @@ -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 @@ -681,12 +615,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # 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 # @@ -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 #include +#include #ifdef ARCH_MM_MMU -#include -#include -#include -#include #include +#include 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 #include #include @@ -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 #include +#include +#include #ifdef ARCH_MM_MMU -#include -#include -#include -#include #include +#include -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 +#include + #include #ifdef ARCH_MM_MMU -#include -#include -#include -#include +#include #include +#include +#include -#include #include #include +#include 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 #include #include -#include #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 #include #include @@ -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 -#ifdef ARCH_MM_MMU +#ifdef RT_USING_SMART #include -#include #include +#include -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 -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 + #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 #ifdef ARCH_MM_MMU -#include #include #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 #include +#include /** * 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 - -#ifdef ARCH_MM_MMU -#include - -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 -#include - -#include - -#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 #include -#include #include +#include +#include +#include /* 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 #include #include +#include +#include #include #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 #include +#include #ifdef ARCH_MM_MMU -#include -#include -#include -#include +#include #include #include +#include -int lwp_user_space_init(struct rt_lwp *lwp) +#include +#include +#include +#include +#include +#include + +#define DBG_TAG "LwP" +#define DBG_LVL DBG_LOG +#include + +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 - } -} - -static void unmap_range(struct rt_lwp *lwp, void *addr, size_t size, int pa_need_free) -{ - void *va = RT_NULL, *pa = RT_NULL; - int i = 0; - - for (va = addr, i = 0; i < size; va = (void *)((char *)va + ARCH_PAGE_SIZE), i += ARCH_PAGE_SIZE) - { - pa = rt_hw_mmu_v2p(&lwp->mmu_info, va); - if (pa) - { - rt_hw_mmu_unmap(&lwp->mmu_info, va, ARCH_PAGE_SIZE); - if (pa_need_free) - { - rt_pages_free((void *)((char *)pa - PV_OFFSET), 0); - } - } + rt_hw_aspace_switch(aspace); } } void lwp_unmap_user_space(struct rt_lwp *lwp) { - struct lwp_avl_struct *node = RT_NULL; - - while ((node = lwp_map_find_first(lwp->map_area)) != 0) - { - 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); - - switch (ma->type) - { - 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; - } - unmap_range(lwp, (void *)ma->addr, ma->size, pa_need_free); - lwp_map_area_remove(&lwp->map_area, ma->addr); - } - + rt_free(lwp->lwp_obj); + rt_aspace_delete(lwp->aspace); arch_user_space_vtable_free(lwp); } -static void *_lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, int text) +static const char *user_get_name(rt_varea_t varea) +{ + char *name; + if (varea->flag & MMF_TEXT) + { + name = "user.text"; + } + else + { + if (varea->start == (void *)USER_STACK_VSTART) + { + 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; +} + +static void _user_do_page_fault(struct rt_varea *varea, + struct rt_mm_fault_msg *msg) +{ + 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; + + if (lwp_objs->source) + { + void *paddr = rt_hw_mmu_v2p(lwp_objs->source, msg->vaddr); + if (paddr != ARCH_MAP_FAILED) + { + vaddr = paddr - PV_OFFSET; + + 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)) + { + /* if data segment not exist in source do a fallback */ + rt_mm_dummy_mapper.on_page_fault(varea, msg); + } + } + else /* if (!lwp_objs->source), no aspace as source data */ + { + rt_mm_dummy_mapper.on_page_fault(varea, msg); + } +} + +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) { 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) + rt_mem_obj_t mem_obj = &lwp->lwp_obj->mem_obj; + va = map_va ? map_va : ARCH_MAP_FAILED; + + ret = rt_aspace_map(lwp->aspace, &va, map_size, MMU_MAP_U_RWCB, flags, + mem_obj, 0); + if (ret != RT_EOK) { - return 0; + va = RT_NULL; + LOG_I("lwp_map_user: failed to map %lx with size %lx", map_va, + map_size); } - 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) - { - unmap_range(lwp, va, map_size, 1); - return 0; - } 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; - - 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) - { - rt_mm_unlock(); - return -1; - } - 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)) - { - pa_need_free = 1; - } - 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 err; + err = rt_aspace_unmap(lwp->aspace, va, 1); + return err; } -int lwp_dup_user(struct lwp_avl_struct *ptree, void *arg) +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) + { + 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; + } + } + else + { + 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; + } + } + } +} + +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: - { - 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; - } - break; - default: - RT_ASSERT(0); - break; + /* 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); + } } - if (va != (void *)ma->addr) + 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)) + { + _dup_varea(varea, self_lwp, new_lwp->aspace); + } + } + } + + 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) - { - ret = (void *)((char *)ret + offset); - } - return ret; -} + if (map_va == RT_NULL) + map_va = ARCH_MAP_FAILED; -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); + 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) + { + va = RT_NULL; + LOG_W("%s", __func__); + } + + 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 -#include +#include +#include +#include +#include #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 - -#include -#include - -#ifdef ARCH_MM_MMU - -#include -#include - -#define ARCH_PAGE_LIST_SIZE (ARCH_ADDRESS_WIDTH_BITS - ARCH_PAGE_SHIFT) - -#define DBG_TAG "PAGE" -#define DBG_LVL DBG_WARNING -#include - -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 #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 + +#include +#include "avl_adpt.h" +#include "mm_aspace.h" +#include "mm_private.h" + +#define DBG_TAG "MM" +#define DBG_LVL DBG_INFO +#include + +/** + * @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 +#include +#include +#include + +#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 +#include +#include +#include + +#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 +#include + +#ifndef RT_USING_SMART +#define PV_OFFSET 0 +#endif + +#define DBG_TAG "mm.aspace" +#define DBG_LVL DBG_INFO +#include + +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 +#include +#include + +#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 + +#ifdef RT_USING_SMART +#include +#include +#include "mm_aspace.h" +#include "mm_fault.h" +#include "mm_flag.h" +#include "mm_private.h" +#include +#include + +#define DBG_TAG "mm.fault" +#define DBG_LVL DBG_INFO +#include + +#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 +#include +#include + +#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 + +#include "mm_aspace.h" +#include "mm_fault.h" +#include "mm_page.h" +#include + +#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 + +#include +#include +#include + +#include "mm_fault.h" +#include "mm_private.h" +#include "mm_aspace.h" +#include "mm_flag.h" +#include "mm_page.h" +#include + +#define DBG_TAG "mm.page" +#define DBG_LVL DBG_WARNING +#include + +#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 +#include +#include + +#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 +#include + +/** + * @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 +#include + +#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 +#include + +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 +#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 +#include #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 -#include #include +#include +#include +#include +#include +#include +#include "mm_aspace.h" +#include "mm_page.h" #include "mmu.h" +#include "tlb.h" #ifdef RT_USING_SMART +#include "ioremap.h" #include -#include #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 -#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_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_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) + void *unmap_va = v_addr; + size_t npages = size >> ARCH_PAGE_SHIFT; + + // TODO trying with HUGEPAGE here + while (npages--) { - return -1; - } - if (pa & ARCH_SECTION_MASK) - { - return -1; - } - for (i = 0; i < count; i++) - { - 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; + + if (ret == 0) + { + return unmap_va; + } + + return NULL; } -/************ 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) +void rt_hw_mmu_unmap(rt_aspace_t aspace, void *v_addr, size_t size) { - unsigned long val64; + // caller guarantee that v_addr & size are page aligned + size_t npages = size >> ARCH_PAGE_SHIFT; - val64 = 0x00447fUL; - __asm__ volatile("msr MAIR_EL1, %0\n dsb sy\n"::"r"(val64)); + if (!aspace->page_table) + { + return; + } - /* 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)); + while (npages--) + { + _kenrel_unmap_4K(aspace->page_table, v_addr); + v_addr += ARCH_PAGE_SIZE; + } } -/* dump 2nd level page table */ -void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) +void rt_hw_aspace_switch(rt_aspace_t aspace) { -} + if (aspace != &rt_kernel_space) + { + void *pgtbl = aspace->page_table; + pgtbl = _rt_kmem_v2p(pgtbl); + uintptr_t tcr; -void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb) -{ -} + __asm__ volatile("msr ttbr0_el1, %0" ::"r"(pgtbl) : "memory"); -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) -{ - unsigned long count; + __asm__ volatile("mrs %0, tcr_el1" : "=r"(tcr)); + tcr &= ~(1ul << 7); + __asm__ volatile("msr tcr_el1, %0\n" + "isb" ::"r"(tcr) + : "memory"); - if (vaddrStart & ARCH_SECTION_MASK) - { - while (1); + rt_hw_tlb_invalidate_all_local(); } - if (paddrStart & ARCH_SECTION_MASK) - { - while (1); - } - if (vaddrStart > vaddrEnd) - { - while (1); - } - count = vaddrEnd + 1; - if (count & ARCH_SECTION_MASK) - { - while (1); - } - count -= vaddrStart; - if (count == 0) - { - while (1); - } - 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,434 +372,180 @@ 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; - - return 0; -} - -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 loop_pages; - size_t va; - size_t find_va = 0; - int n = 0; - size_t i; - - if (!pages) - { - return 0; - } - - if (!mmu_info) - { - return 0; - } - - 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 (_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; -} - -static int check_vaddr(rt_mmu_info *mmu_info, void *va, int pages) -{ - size_t loop_va; - - if (!pages) - { - return -1; - } - - if (!mmu_info) - { - return -1; - } - - loop_va = ((size_t)va >> ARCH_SECTION_SHIFT); - if (loop_va < mmu_info->vstart || loop_va > mmu_info->vend) - { - return -1; - } - loop_va += ((pages << ARCH_PAGE_SHIFT) >> ARCH_SECTION_SHIFT); - if (loop_va < mmu_info->vstart || loop_va > mmu_info->vend + 1) - { - return -1; - } - - loop_va = (size_t)va & ~ARCH_PAGE_MASK; - while (pages--) - { - if (_rt_hw_mmu_v2p(mmu_info, (void *)loop_va)) - { - return -1; - } - loop_va += ARCH_PAGE_SIZE; - } - return 0; -} - -static void __rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, size_t npages) -{ - size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK; - - if (!mmu_info || !mmu_info->vtable) - { - return; - } - - while (npages--) - { - _kenrel_unmap_4K(mmu_info->vtable, (void *)loop_va); - loop_va += ARCH_PAGE_SIZE; - } -} - -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 (mmu_info) - { - while (npages--) - { - 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; - } - } - return ret; -} -#endif - -static void rt_hw_cpu_tlb_invalidate(void) -{ - __asm__ volatile("tlbi vmalle1\n dsb sy\n isb sy\n"); -} - -#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) -{ - size_t pa_s, pa_e; - size_t vaddr; - int pages; - int ret; - - 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) - { - 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; - } - } - else - { - 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)); - } - rt_exit_critical(); - } - return 0; -} + rt_aspace_init(aspace, (void *)KERNEL_VADDR_START, 0 - KERNEL_VADDR_START, + vtable); #else -void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr) -{ - return p_addr; -} + rt_aspace_init(aspace, (void *)0x1000, RTOS_VEND - (void *)0x1000, vtable); #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) -{ - size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK; - size_t loop_pa; + _init_region(v_address, size); - if (!mmu_info) - { - 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; - } - 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_unmap(mmu_info, v_addr, npages); - return -1; - } -} - -void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr) -{ - size_t vaddr; - size_t offset; - int pages; - int ret; - - if (!size) - { - 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; - } - } - 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) - { - 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) +/************ 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) { - size_t va_s, va_e; - int pages; + unsigned long val64; - 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(); + 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)); } -void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, size_t size, size_t attr) +struct page_table { - void *ret; + unsigned long page[512]; +}; - 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) +static struct page_table *__init_page_array; +static unsigned long __page_off = 0UL; +unsigned long get_free_page(void) { - 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 - -void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_size_t desc_nr) -{ - rt_memset((void *)MMUTable, 0, sizeof(MMUTable)); - rt_memset((void *)MMUPage, 0, sizeof(MMUPage)); - - /* set page table */ - for (; desc_nr > 0; --desc_nr) + if (!__init_page_array) { - rt_hw_mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end, mdesc->paddr_start, mdesc->attr); - ++mdesc; + 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 */ } - - rt_hw_cpu_dcache_clean((void *)MMUTable, sizeof(MMUTable)); + __page_off++; + return (unsigned long)(__init_page_array[__page_off - 1].page); } - -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) +static int _map_single_page_2M(unsigned long *lv0_tbl, unsigned long va, + unsigned long pa, unsigned long attr) { int level; - unsigned long va = (unsigned long)v_addr; - unsigned long pa; - unsigned long *cur_lv_tbl; + unsigned long *cur_lv_tbl = lv0_tbl; unsigned long page; unsigned long off; - unsigned long off_addr; int level_shift = MMU_ADDRESS_BITS; - if (!mmu_info) + if (va & ARCH_SECTION_MASK) { - return (void *)0; + return MMU_MAP_ERROR_VANOTALIGN; } - cur_lv_tbl = mmu_info->vtable; - for (level = 0; level < MMU_TBL_PAGE_4k_LEVEL; level++) + 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)) { - return (void *)0; + 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; } page = cur_lv_tbl[off]; if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK) { - off_addr = va & ((1UL << level_shift) - 1); - pa = (page & MMU_ADDRESS_MASK); - pa += off_addr; - return (void *)pa; + /* 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 _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 unsigned long *_query(rt_aspace_t aspace, void *vaddr, int *plvl_shf) +{ + 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; + + cur_lv_tbl = aspace->page_table; + RT_ASSERT(cur_lv_tbl); + + 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) + { + *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; @@ -987,27 +554,110 @@ void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr) off = (va >> ARCH_PAGE_SHIFT); off &= MMU_LEVEL_MASK; page = cur_lv_tbl[off]; + if (!(page & MMU_TYPE_USED)) { return (void *)0; } - pa = (page & MMU_ADDRESS_MASK); - pa += (va & ARCH_PAGE_MASK); - return (void *)pa; + *plvl_shf = level_shift; + return &cur_lv_tbl[off]; } -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) { - void *ret; + int level_shift; + unsigned long paddr; + unsigned long *pte = _query(aspace, v_addr, &level_shift); - rt_mm_lock(); - ret = _rt_hw_mmu_v2p(mmu_info, v_addr); - rt_mm_unlock(); - return ret; + if (pte) + { + paddr = *pte & MMU_ADDRESS_MASK; + paddr |= (uintptr_t)v_addr & ((1ul << level_shift) - 1); + } + else + { + paddr = (unsigned long)ARCH_MAP_FAILED; + } + return (void *)paddr; } +static int _noncache(uintptr_t *pte) +{ + 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)) + { + *pte = (entry & ~idx_mask) | (NORMAL_NOCACHE_MEM << idx_shift); + } + else + { + // do not support other type to be noncache + err = RT_ENOSYS; + } + return err; +} -void rt_hw_mmu_setup_early(unsigned long *tbl0, unsigned long *tbl1, unsigned long size, unsigned long pv_off) +static int _cache(uintptr_t *pte) +{ + 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)) + { + *pte = (entry & ~idx_mask) | (NORMAL_MEM << idx_shift); + } + else + { + // do not support other type to be cache + err = -RT_ENOSYS; + } + return err; +} + +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_shift; + 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_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; + } + } + else + { + err = -RT_ENOSYS; + } + + return err; +} + +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 +#include /* 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); - -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); - -#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_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); +struct rt_aspace; void rt_hw_mmu_ktbl_set(unsigned long tbl); -void *rt_hw_mmu_tbl_get(); -void rt_hw_mmu_switch(void *mmu_table); +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); -void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_size_t desc_nr); -void rt_hw_mmu_init(void); +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); -extern rt_mmu_info mmu_info; +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)); +} + +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; +} + +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 +#include +#include +#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 #include "interrupt.h" +#include "mm_fault.h" #include @@ -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 + /* 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 #include - #include "cp15.h" +#include "mm_page.h" #include "mmu.h" +#include +#include #ifdef RT_USING_SMART #include -#include "page.h" +#include +#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) -{ - size_t loop_va = (size_t)va & ~ARCH_PAGE_MASK; - size_t l1_off, l2_off; - size_t *mmu_l1, *mmu_l2; - - if (!pages) - { - return -1; - } - - if (!mmu_info) - { - return -1; - } - - l1_off = ((size_t)va >> ARCH_SECTION_SHIFT); - if (l1_off < mmu_info->vstart || l1_off > mmu_info->vend) - { - return -1; - } - l1_off += ((pages << ARCH_PAGE_SHIFT) >> ARCH_SECTION_SHIFT); - if (l1_off < mmu_info->vstart || l1_off > mmu_info->vend + 1) - { - return -1; - } - - while (pages--) - { - 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); - if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK) - { - return -1; - } - } - 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 void _kenrel_unmap_4K(unsigned long *lv0_tbl, void *v_addr) { size_t loop_va = (size_t)v_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) + { + mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - PV_OFFSET); + } + else { return; } - while (npages--) + if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK) { - l1_off = (loop_va >> ARCH_SECTION_SHIFT); - if (l1_off < mmu_info->vstart || l1_off > mmu_info->vend) - { - return; - } + *(mmu_l2 + l2_off) = 0; + /* cache maintain */ + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l2 + l2_off, 4); - 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) + if (rt_pages_free(mmu_l2, 0)) { - mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off); + *mmu_l1 = 0; + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l1, 4); } - else - { - return; - } - - 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); - - 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; } -static int __rt_hw_mmu_map(rt_mmu_info *mmu_info, void* v_addr, void* p_addr, size_t npages, size_t attr) +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 -1; + mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - PV_OFFSET); + rt_page_ref_inc(mmu_l2, 0); + } + else + { + 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 + PV_OFFSET) | 0x1); + /* cache maintain */ + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_l1, 4); + } + else + { + /* error, quit */ + return -1; + } + } + + *(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; + + return 0; +} + +void *rt_hw_mmu_map(rt_aspace_t aspace, void *v_addr, void *p_addr, size_t size, + size_t attr) +{ + int ret = -1; + void *unmap_va = v_addr; + size_t npages = size >> ARCH_PAGE_SHIFT; + + // TODO trying with HUGEPAGE here + while (npages--) + { + ret = _kenrel_map_4K(aspace->page_table, v_addr, p_addr, attr); + if (ret != 0) + { + /* error, undo map */ + while (unmap_va != v_addr) + { + rt_enter_critical(); + _kenrel_unmap_4K(aspace->page_table, (void *)unmap_va); + rt_exit_critical(); + + unmap_va += ARCH_PAGE_SIZE; + } + break; + } + v_addr += ARCH_PAGE_SIZE; + p_addr += ARCH_PAGE_SIZE; + } + + if (ret == 0) + { + return v_addr; + } + + return NULL; +} + +void rt_hw_mmu_unmap(rt_aspace_t aspace, void *v_addr, size_t size) +{ + // caller guarantee that v_addr & size are page aligned + size_t npages = size >> ARCH_PAGE_SHIFT; + + if (!aspace->page_table) + { + return; } 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; + rt_enter_critical(); + _kenrel_unmap_4K(aspace->page_table, v_addr); + rt_exit_critical(); - if (*mmu_l1 & ARCH_MMU_USED_MASK) + v_addr += ARCH_PAGE_SIZE; + } +} + +void rt_hw_aspace_switch(rt_aspace_t aspace) +{ + if (aspace != &rt_kernel_space) + { + void *pgtbl = aspace->page_table; + pgtbl = _rt_kmem_v2p(pgtbl); + + rt_hw_mmu_switch(pgtbl); + + rt_hw_tlb_invalidate_all_local(); + } +} + +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) { - mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off); - rt_page_ref_inc(mmu_l2, 0); + 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 { - 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 - { - /* error, unmap and quit */ - __rt_hw_mmu_unmap(mmu_info, v_addr, npages); - return -1; - } + mtbl[va] = 0; } - - *(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; - } - - return 0; -} - -void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr) -{ - size_t pa_s, pa_e; - size_t vaddr; - int pages; - int ret; - - 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) - { - 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; - } - } - else - { - 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)); - } - rt_exit_critical(); - } - return 0; -} - -static int __rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void* v_addr, size_t npages, size_t attr) -{ - 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) - { - 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; - - 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_unmap(mmu_info, v_addr, npages); - return -1; } } -void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr) -{ - size_t vaddr; - size_t offset; - int pages; - int ret; - - if (!size) - { - 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; - } - } - 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) - { - 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(); -} - -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 +#include #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); -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_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; +} + +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 */ + 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, 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 +#include +#include + +#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 -#include -#include #include +#include +#include +#include #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 +#ifdef RT_USING_SMART +#include + +#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 #include "cpuport.h" +#include "sbi.h" #include "stack.h" #include @@ -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 + 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,47 +8,270 @@ * 2021-01-30 lizhirui first version */ +#include "rtconfig.h" #include -#include -#include -#include "page.h" -#include -#include +#include +#include + #include +#include +#include +#include +#include +#include -#include "riscv.h" -#include "riscv_mmu.h" -#include "mmu.h" +#ifdef RT_USING_SMART +#include +#include +#include +#endif -void *current_mmu_table = RT_NULL; +#define DBG_TAG "MMU" +#define DBG_LVL DBG_LOG +#include -static void rt_hw_cpu_tlb_invalidate() +#ifndef RT_USING_SMART +#define PV_OFFSET 0 +#define USER_VADDR_START 0 +#endif + +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; + + 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 *)aspace->page_table) + l1_off; + + if (PTE_USED(*mmu_l1)) + { + mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1), PV_OFFSET); + } + else + { + mmu_l2 = (rt_size_t *)rt_pages_alloc(0); + + if (mmu_l2) + { + 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; + } + } + + 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)), PV_OFFSET); + } + else + { + mmu_l3 = (rt_size_t *)rt_pages_alloc(0); + + if (mmu_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 + { + 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; } -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) +/** 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) { - size_t l1_off,va_s,va_e; + int ret = -1; + void *unmap_va = v_addr; + size_t npages = size >> ARCH_PAGE_SHIFT; + + // TODO trying with HUGEPAGE here + while (npages--) + { + ret = _map_one_page(aspace, v_addr, p_addr, attr); + if (ret != 0) + { + /* 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; + } + v_addr += ARCH_PAGE_SIZE; + p_addr += ARCH_PAGE_SIZE; + } + + if (ret == 0) + { + return unmap_va; + } + + return NULL; +} + +static void _unmap_pte(rt_size_t *pentry, rt_size_t *lvl_entry[], int level) +{ + int loop_flag = 1; + while (loop_flag) + { + loop_flag = 0; + *pentry = 0; + rt_hw_cpu_dcache_clean(pentry, sizeof(*pentry)); + + // we don't handle level 0, which is maintained by caller + if (level > 0) + { + void *page = (void *)((rt_ubase_t)pentry & ~ARCH_PAGE_MASK); + + // decrease reference from child page to parent + rt_pages_free(page, 0); + + int free = rt_page_ref_get(page, 0); + if (free == 1) + { + rt_pages_free(page, 0); + pentry = lvl_entry[--level]; + loop_flag = 1; + } + } + } +} + +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); + 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]; + + // find leaf page table entry + while (PTE_USED(*pentry) && !PAGE_IS_LEAF(*pentry)) + { + 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; + } + + // clear PTE & setup its + if (PTE_USED(*pentry)) + { + _unmap_pte(pentry, lvl_entry, i); + } + + return unmapped; +} + +/** 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; + + while (size > 0) + { + MM_PGTBL_LOCK(aspace); + unmapped = _unmap_area(aspace, v_addr, size); + MM_PGTBL_UNLOCK(aspace); + + // when unmapped == 0, region not exist in pgtbl + if (!unmapped || unmapped > size) + break; + + size -= unmapped; + v_addr += unmapped; + } +} + +#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 + +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) +{ + size_t l1_off, va_s, va_e; rt_base_t level; - if((!mmu_info) || (!vtable)) + if ((!aspace) || (!vtable)) { return -1; } @@ -56,566 +279,89 @@ int rt_hw_mmu_map_init(rt_mmu_info *mmu_info,void *v_address,rt_size_t size,rt_s va_s = (rt_size_t)v_address; va_e = ((rt_size_t)v_address) + size - 1; - if(va_e < va_s) + if (va_e < va_s) { return -1; } - //convert address to level 1 page frame id + // convert address to PPN2 index va_s = GET_L1(va_s); va_e = GET_L1(va_e); - if(va_s == 0) + 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++) + // vtable initialization check + for (l1_off = va_s; l1_off <= va_e; l1_off++) { size_t v = vtable[l1_off]; - if(v) + if (v) { - rt_hw_interrupt_enable(level); - return 0; + return -1; } } - mmu_info -> vtable = vtable; - mmu_info -> vstart = va_s; - mmu_info -> vend = va_e; - mmu_info -> pv_off = pv_off; + rt_aspace_init(&rt_kernel_space, (void *)0x1000, USER_VADDR_START - 0x1000, + vtable); - rt_hw_interrupt_enable(level); + _init_region(v_address, size); return 0; } -void rt_hw_mmu_kernel_map_init(rt_mmu_info *mmu_info,rt_size_t vaddr_start,rt_size_t size) +const static int max_level = + (ARCH_VADDR_WIDTH - ARCH_PAGE_SHIFT) / ARCH_INDEX_WIDTH; + +static inline uintptr_t _get_level_size(int level) { - 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(); + return 1ul << (ARCH_PAGE_SHIFT + (max_level - level) * ARCH_INDEX_WIDTH); } -//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) +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 find_l1 = 0,find_l2 = 0,find_l3 = 0; - rt_size_t 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 = ((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); - - 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); - } - } - } - } - 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 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_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; - } - } - } - - loop_va += PAGE_SIZE; - } - - return 0; -} - -static void __rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t npages) -{ - 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--) - { - 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)--; - - if(!*ref_cnt) - { - //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; - - ref_cnt = mmu_l2 + __SIZE(VPN1_BIT); - (*ref_cnt)--; - - if(!*ref_cnt) - { - //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)); - } - } - - 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) -{ - 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); - - if(!mmu_info) - { - return -1; - } - - while(npages--) - { - 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); - - 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; - } - } - - 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); - - 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; - } - } - - 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))); - - loop_va += PAGE_SIZE; - loop_pa += 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) - { - return 0; - } - - 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; - - if(v_addr) - { - 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; - } - - vaddr = __UMASKVALUE(vaddr,PAGE_OFFSET_MASK); - - 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)); - } - } - - 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) -{ - 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; - - if(!mmu_info) - { - return -1; - } - - while(npages--) - { - 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; - } - - return 0; - - err: - va = (void *)__UMASKVALUE((rt_size_t)v_addr,PAGE_OFFSET_MASK); - - for(i = 0;i < npages;i++) - { - pa = rt_hw_mmu_v2p(mmu_info,va); - - if(pa) - { - rt_pages_free((void *)PPN_TO_VPN(pa,mmu_info -> pv_off),0); - } - - va = (void *)((rt_uint8_t *)va + PAGE_SIZE); - } - - __rt_hw_mmu_unmap(mmu_info,v_addr,npages); - return -1; -} - -void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size,rt_size_t attr) -{ - rt_size_t vaddr; - rt_size_t offset; - rt_size_t pages; - int ret; - - if(!size) - { - return 0; - } - - offset = GET_PF_OFFSET((rt_size_t)v_addr); - size += (offset + PAGE_SIZE - 1); - pages = size >> PAGE_OFFSET_BIT; - - if(v_addr) - { - vaddr = __UMASKVALUE((rt_size_t)v_addr,PAGE_OFFSET_MASK); - - 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_auto(mmu_info,(void *)vaddr,pages,attr); - - if(ret == 0) - { - rt_hw_cpu_tlb_invalidate(); - return (void *)(vaddr | offset); - } - } - - 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; - - 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; -} - -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; -} - -void rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size) -{ - rt_base_t level; - - level = rt_hw_interrupt_disable(); - _rt_hw_mmu_unmap(mmu_info,v_addr,size); - rt_hw_interrupt_enable(level); -} - -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 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 (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); - - if(PTE_USED(*(mmu_l2 + l2_off))) + if (*mmu_l1 & PTE_XWR_MASK) { - 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); + *level = 1; + return mmu_l1; + } - if(PTE_USED(*(mmu_l3 + l3_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) { - 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)); + *level = 2; + return mmu_l2 + l2_off; + } + + 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; } } } @@ -623,13 +369,137 @@ 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; - level = rt_hw_interrupt_disable(); - ret = _rt_hw_mmu_v2p(mmu_info,v_addr); - rt_hw_interrupt_enable(level); - return ret; + if (pte) + { + paddr = GET_PADDR(*pte); + paddr |= ((intptr_t)vaddr & (_get_level_size(level) - 1)); + } + else + { + paddr = 0; + } + 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; + } + + return err; +} + +/** + * @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++) + { + 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_aspace_switch(&rt_kernel_space); + rt_page_cleanup(); +} + +void rt_hw_mmu_kernel_map_init(rt_aspace_t aspace, rt_size_t vaddr_start, rt_size_t size) +{ + 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; + } + + 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 +#include + +/* 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 #include +#include #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 PAGE_IS_LEAF(pte) __MASKVALUE(pte, PAGE_ATTR_RWX) -#define PTE_USED(pte) __MASKVALUE(pte,PTE_V) +#define PTE_USED(pte) __MASKVALUE(pte, PTE_V) -#define mmu_flush_tlb() do{asm volatile("sfence.vma x0,x0");}while(0) +/** + * 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 -//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_VADDR_WIDTH 39 +#define SATP_MODE SATP_MODE_SV39 + +#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_XWR_MASK 0xe + +#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) + +#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 #include +#include /* 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 +#include +#include + +#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) + if (!(sp->sstatus & 0x100)) { - arch_expand_user_stack((void *)stval); - return; - } -#endif - if(id < sizeof(Exception_Name) / sizeof(const char *)) - { - msg = Exception_Name[id]; - } - else - { - 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,37 +6,50 @@ * Change Logs: * Date Author Notes * 2021-01-30 lizhirui first version + * 2022-12-13 WangXiaoyao Port to new mm */ #include -#include +#include +#include + +#include +#include +#include +#include +#include +#include #ifdef RT_USING_SMART +#include +#include +#include +#endif -#include -#include -#include -#include -#include -#include - -#define DBG_TAG "mmu" -#define DBG_LVL DBG_INFO +#define DBG_TAG "hw.mmu" +#define DBG_LVL DBG_LOG #include -#include "riscv.h" -#include "riscv_mmu.h" -#include "mmu.h" +#ifndef RT_USING_SMART +#define PV_OFFSET 0 +#define USER_VADDR_START 0 +#endif -void *current_mmu_table = RT_NULL; +static size_t _unmap_area(struct rt_aspace *aspace, void *v_addr, size_t size); -volatile rt_ubase_t MMUTable[__SIZE(VPN2_BIT)] __attribute__((aligned(4 * 1024))); +static void *current_mmu_table = RT_NULL; -static void rt_hw_cpu_tlb_invalidate() +volatile __attribute__((aligned(4 * 1024))) +rt_ubase_t MMUTable[__SIZE(VPN2_BIT)]; + +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); + current_mmu_table = 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(); } void *rt_hw_mmu_tbl_get() @@ -44,21 +57,221 @@ 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; + + 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 *)aspace->page_table) + l1_off; + + if (PTE_USED(*mmu_l1)) + { + mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1), PV_OFFSET); + } + else + { + mmu_l2 = (rt_size_t *)rt_pages_alloc(0); + + if (mmu_l2) + { + 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; + } + } + + 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)), PV_OFFSET); + } + else + { + mmu_l3 = (rt_size_t *)rt_pages_alloc(0); + + if (mmu_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 + { + 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; } -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) +/** 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) +{ + int ret = -1; + void *unmap_va = v_addr; + size_t npages = size >> ARCH_PAGE_SHIFT; + + // TODO trying with HUGEPAGE here + while (npages--) + { + ret = _map_one_page(aspace, v_addr, p_addr, attr); + if (ret != 0) + { + /* 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; + } + v_addr += ARCH_PAGE_SIZE; + p_addr += ARCH_PAGE_SIZE; + } + + if (ret == 0) + { + return unmap_va; + } + + return NULL; +} + +static void _unmap_pte(rt_size_t *pentry, rt_size_t *lvl_entry[], int level) +{ + int loop_flag = 1; + while (loop_flag) + { + loop_flag = 0; + *pentry = 0; + rt_hw_cpu_dcache_clean(pentry, sizeof(*pentry)); + + // we don't handle level 0, which is maintained by caller + if (level > 0) + { + void *page = (void *)((rt_ubase_t)pentry & ~ARCH_PAGE_MASK); + + // decrease reference from child page to parent + rt_pages_free(page, 0); + + int free = rt_page_ref_get(page, 0); + if (free == 1) + { + rt_pages_free(page, 0); + pentry = lvl_entry[--level]; + loop_flag = 1; + } + } + } +} + +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); + 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]; + + // find leaf page table entry + while (PTE_USED(*pentry) && !PAGE_IS_LEAF(*pentry)) + { + 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; + } + + // clear PTE & setup its + if (PTE_USED(*pentry)) + { + _unmap_pte(pentry, lvl_entry, i); + } + + return unmapped; +} + +/** 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; + + while (size > 0) + { + MM_PGTBL_LOCK(aspace); + unmapped = _unmap_area(aspace, v_addr, size); + MM_PGTBL_UNLOCK(aspace); + + // when unmapped == 0, region not exist in pgtbl + if (!unmapped || unmapped > size) + break; + + size -= unmapped; + v_addr += unmapped; + } +} + +#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 + +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) { size_t l1_off, va_s, va_e; rt_base_t level; - if ((!mmu_info) || (!vtable)) + if ((!aspace) || (!vtable)) { return -1; } @@ -80,8 +293,6 @@ int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void *v_address, rt_size_t size, r return -1; } - rt_mm_lock(); - // vtable initialization check for (l1_off = va_s; l1_off <= va_e; l1_off++) { @@ -89,502 +300,68 @@ int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void *v_address, rt_size_t size, r 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; + rt_aspace_init(&rt_kernel_space, (void *)0x1000, USER_VADDR_START - 0x1000, + vtable); + _init_region(v_address, size); return 0; } -void rt_hw_mmu_kernel_map_init(rt_mmu_info *mmu_info, rt_size_t vaddr_start, rt_size_t size) +const static int max_level = + (ARCH_VADDR_WIDTH - ARCH_PAGE_SHIFT) / ARCH_INDEX_WIDTH; + +static inline uintptr_t _get_level_size(int level) { - 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; - } - - rt_hw_cpu_tlb_invalidate(); + return 1ul << (ARCH_PAGE_SHIFT + (max_level - level) * ARCH_INDEX_WIDTH); } -// 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; - - if (!pages || !mmu_info) - { - return 0; - } - - 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); - - 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; -} - -// 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_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; - } - } - } - - loop_va += PAGE_SIZE; - } - - return 0; -} - -static void __rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, rt_size_t npages) -{ - 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; - } -} - -static int _mmu_map_one_page(rt_mmu_info *mmu_info, size_t va, size_t 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); - - 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(0); - - if (mmu_l2) - { - 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); - rt_hw_cpu_dcache_clean(mmu_l1, sizeof(*mmu_l1)); - } - else - { - return -1; - } - } - - 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(0); - - if (mmu_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, mmu_info->pv_off), 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 - { - 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; -} - -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_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; - } - - while (npages--) - { - if (_mmu_map_one_page(mmu_info, loop_va, loop_pa, attr) != 0) - { - __rt_hw_mmu_unmap(mmu_info, v_addr, npages); - return -1; - } - - loop_va += PAGE_SIZE; - loop_pa += 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) - { - return 0; - } - - 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; - - if (v_addr) - { - 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; - } - - vaddr = __UMASKVALUE(vaddr, PAGE_OFFSET_MASK); - - 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)); - } - } - - 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) -{ - 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; - - if (!mmu_info) - { - return -1; - } - - while (npages--) - { - 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; - } - - return 0; - -err: - va = (void *)__UMASKVALUE((rt_size_t)v_addr, PAGE_OFFSET_MASK); - - for (i = 0; i < npages; i++) - { - pa = rt_hw_mmu_v2p(mmu_info, va); - - if (pa) - { - rt_pages_free((void *)PPN_TO_VPN(pa, mmu_info->pv_off), 0); - } - - va = (void *)((rt_uint8_t *)va + PAGE_SIZE); - } - - __rt_hw_mmu_unmap(mmu_info, v_addr, npages); - return -1; -} - -void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, rt_size_t size, rt_size_t attr) -{ - rt_size_t vaddr; - rt_size_t offset; - rt_size_t pages; - int ret; - - if (!size) - { - return 0; - } - - offset = GET_PF_OFFSET((rt_size_t)v_addr); - size += (offset + PAGE_SIZE - 1); - pages = size >> PAGE_OFFSET_BIT; - - if (v_addr) - { - vaddr = __UMASKVALUE((rt_size_t)v_addr, PAGE_OFFSET_MASK); - - 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_auto(mmu_info, (void *)vaddr, pages, attr); - - if (ret == 0) - { - rt_hw_cpu_tlb_invalidate(); - return (void *)(vaddr | offset); - } - } - - 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_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, 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; -} - -void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, rt_size_t size) -{ - rt_base_t level; - - 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) +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; - rt_mm_lock(); - ret = _rt_hw_mmu_v2p(mmu_info, v_addr); - rt_mm_unlock(); - return ret; + 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; + } + + 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 +#include /* 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)) - -typedef struct -{ - size_t *vtable; - size_t vstart; - size_t vend; - size_t pv_off; -} rt_mmu_info; - -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); - -void rt_hw_mmu_setup(rt_mmu_info *mmu_info, struct mem_desc *mdesc, int desc_nr); +#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 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 +#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(); +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; +} + +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 #include -#include #include -#include +#include #include +#include #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 #include +#include /* 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 +#include +#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 #include 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 #include #include -#include #include #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 +#include +#include + +#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 #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) { - if (arch_expand_user_stack((void *)stval)) + 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) + { + 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)