[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
This commit is contained in:
Shell
2023-01-08 21:08:55 -05:00
committed by GitHub
parent 7f9ccd3c80
commit 7450ef6c4d
121 changed files with 5947 additions and 7041 deletions
+154 -15
View File
File diff suppressed because it is too large Load Diff
+8 -5
View File
@@ -13,6 +13,7 @@
#include <rtdevice.h>
#include "board.h"
#include "mm_aspace.h"
#include "tick.h"
#include "drv_uart.h"
@@ -40,8 +41,7 @@ rt_region_t init_page_region =
(rt_size_t)RT_HW_PAGE_END};
// 内核页表
volatile rt_size_t MMUTable[__SIZE(VPN2_BIT)] __attribute__((aligned(4 * 1024)));
rt_mmu_info mmu_info;
extern volatile rt_size_t MMUTable[__SIZE(VPN2_BIT)] __attribute__((aligned(4 * 1024)));
#endif
@@ -71,6 +71,7 @@ void primary_cpu_entry(void)
// 初始化BSS
init_bss();
sbi_init();
// 关中断
rt_hw_interrupt_disable();
rt_assert_set_hook(__rt_assert_handler);
@@ -78,18 +79,20 @@ void primary_cpu_entry(void)
entry();
}
#define IOREMAP_SIZE (1ul << 30)
// 这个初始化程序由内核主动调用,此时调度器还未启动,因此在此不能使用依赖线程上下文的函数
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
rt_hw_mmu_map_init(&rt_kernel_space, (void *)(USER_VADDR_START - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t *)MMUTable, 0);
rt_page_init(init_page_region);
rt_hw_mmu_map_init(&mmu_info, (void *)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, (rt_size_t *)MMUTable, 0);
rt_hw_mmu_kernel_map_init(&mmu_info, 0x00000000UL, USER_VADDR_START - 1);
rt_hw_mmu_kernel_map_init(&rt_kernel_space, 0x00000000UL, USER_VADDR_START - 1);
// 将低1GB MMIO区域设置为无Cache与Strong Order访存模式
MMUTable[0] &= ~PTE_CACHE;
MMUTable[0] &= ~PTE_SHARE;
MMUTable[0] |= PTE_SO;
rt_hw_mmu_switch((void *)MMUTable);
rt_hw_aspace_switch(&rt_kernel_space);
#endif
/* initalize interrupt */
rt_hw_interrupt_init();
+1
View File
@@ -11,6 +11,7 @@
#ifndef BOARD_H__
#define BOARD_H__
#include <rtthread.h>
#include <rtconfig.h>
extern unsigned int __bss_start;
+11 -9
View File
@@ -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)
+25 -6
View File
@@ -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 */
+2 -2
View File
@@ -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 = ''
File diff suppressed because it is too large Load Diff
+9 -10
View File
@@ -16,6 +16,7 @@
#include "board.h"
#include "drv_timer.h"
#include "mm_aspace.h"
#include <mmu.h>
#ifdef RT_USING_SMART
@@ -49,8 +50,6 @@ void idle_wfi(void)
* This function will initialize board
*/
rt_mmu_info mmu_info;
extern size_t MMUTable[];
#ifdef RT_USING_SMART
@@ -63,23 +62,23 @@ rt_region_t init_page_region = {
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
rt_hw_mmu_map_init(&mmu_info, (void*)0xf0000000, 0x10000000, MMUTable, PV_OFFSET);
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xf0000000, 0x10000000, MMUTable, PV_OFFSET);
rt_page_init(init_page_region);
rt_hw_mmu_ioremap_init(&mmu_info, (void*)0xf0000000, 0x10000000);
rt_hw_mmu_ioremap_init(&rt_kernel_space, (void*)0xf0000000, 0x10000000);
arch_kuser_init(&mmu_info, (void*)0xffff0000);
arch_kuser_init(&rt_kernel_space, (void*)0xffff0000);
#else
rt_hw_mmu_map_init(&mmu_info, (void*)0x80000000, 0x10000000, MMUTable, 0);
rt_hw_mmu_ioremap_init(&mmu_info, (void*)0x80000000, 0x10000000);
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x80000000, 0x10000000, MMUTable, 0);
rt_hw_mmu_ioremap_init(&rt_kernel_space, (void*)0x80000000, 0x10000000);
#endif
/* initialize hardware interrupt */
rt_hw_interrupt_init();
/* initialize system heap */
rt_system_heap_init(HEAP_BEGIN, HEAP_END);
/* initialize hardware interrupt */
rt_hw_interrupt_init();
rt_components_board_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
-2
View File
@@ -38,6 +38,4 @@ extern int __bss_end;
void rt_hw_board_init(void);
extern rt_mmu_info mmu_info;
#endif
+1 -1
View File
@@ -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
qemu-system-arm -M vexpress-a9 -smp cpus=2 -kernel rtthread.bin -nographic -sd sd.bin -S -s
+2 -124
View File
@@ -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
+1 -1
View File
@@ -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 = ''
File diff suppressed because it is too large Load Diff
+19 -17
View File
@@ -11,16 +11,17 @@
* add smp ipi init
*/
#include "mm_aspace.h"
#include <rthw.h>
#include <rtthread.h>
#include <mmu.h>
#ifdef RT_USING_SMART
#include <page.h>
#include <lwp_arch.h>
#endif
#include "board.h"
#include <mm_page.h>
#include <interrupt.h>
#ifdef RT_USING_FDT
@@ -35,9 +36,13 @@ struct mem_desc platform_mem_desc[] = {
{KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, KERNEL_VADDR_START + PV_OFFSET, NORMAL_MEM}
};
#else
#define PAGE_POOL_SIZE (2ul << 20)
#define PHYMEM_END (0x48000000ul)
struct mem_desc platform_mem_desc[] =
{
{0x40000000, 0x80000000 - 1, 0x40000000, NORMAL_MEM},
{0x40000000, PHYMEM_END - 1, 0x40000000, NORMAL_MEM},
// {PL031_RTC_BASE, PL031_RTC_BASE + 0x1000 - 1, PL031_RTC_BASE, DEVICE_MEM},
// {PL061_GPIO_BASE, PL061_GPIO_BASE + 0x1000 - 1, PL061_GPIO_BASE, DEVICE_MEM},
{PL011_UART0_BASE, PL011_UART0_BASE + ARCH_SECTION_SIZE - 1, PL011_UART0_BASE, DEVICE_MEM},
@@ -63,8 +68,6 @@ void idle_wfi(void)
* This function will initialize board
*/
rt_mmu_info mmu_info;
extern size_t MMUTable[];
#ifdef RT_USING_SMART
@@ -72,30 +75,29 @@ rt_region_t init_page_region = {
PAGE_START,
PAGE_END,
};
#else
rt_region_t init_page_region = {
PHYMEM_END - PAGE_POOL_SIZE,
PHYMEM_END,
};
#endif
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
rt_page_init(init_page_region);
rt_hw_mmu_setup(platform_mem_desc, platform_mem_desc_size);
rt_hw_mmu_map_init(&mmu_info, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET);
arch_kuser_init(&mmu_info, (void*)0xffffffffffff0000);
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET);
#else
rt_hw_mmu_setup(platform_mem_desc, platform_mem_desc_size);
rt_hw_mmu_map_init(&mmu_info, (void*)0x80000000, 0x10000000, MMUTable, 0);
rt_hw_mmu_ioremap_init(&mmu_info, (void*)0x80000000, 0x10000000);
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x80000000, 0x10000000, MMUTable, 0);
#endif
/* initialize hardware interrupt */
rt_hw_interrupt_init();
rt_page_init(init_page_region);
rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
/* initialize system heap */
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
/* initialize hardware interrupt */
rt_hw_interrupt_init();
/* support debug feature before components init */
rt_hw_uart_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
-1
View File
@@ -17,7 +17,6 @@
#include <mmu.h>
#include <ioremap.h>
extern rt_mmu_info mmu_info;
#else
#define rt_ioremap(x, ...) (x)
#endif
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -108
View File
@@ -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 */
File diff suppressed because it is too large Load Diff
@@ -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')
@@ -1,118 +0,0 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
#include <rthw.h>
#if defined(RT_USING_UTEST) && defined(RT_USING_SMART)
#include "riscv_mmu.h"
#include "mmu.h"
#include "utest.h"
#define MAPPED 0
#define UNMAPPED 1
/**
* @brief Meta data to test V2P API, its structure:
*
* {va_start, va_end(included), pa_start, [mapped/unmapped]}
*/
struct mem_desc test_mem_desc[] = {
// mapped region
{0x80000000, 0x80000000 + 0x10000000 - 1, 0x80000000, MAPPED}, // kernel ram region
{0x0, 0x80000000 - 1, 0x0, MAPPED}, // MMIO region 1
// unmapped region
{0x100000000, 0x110000000 - 1, 0x100000000, UNMAPPED}, // region for IOREMAP
};
#define NUM_MEM_DESC (sizeof(test_mem_desc) / sizeof(test_mem_desc[0]))
extern rt_mmu_info mmu_info;
#define TEST_GRANULE_POWER 20
#define TEST_GRANULE_SIZE (1 << TEST_GRANULE_POWER)
// test board mem region
static void test_v2p(void)
{
struct mem_desc *desc = test_mem_desc;
// test on mapped region
for (size_t i = 0; i < NUM_MEM_DESC; i++, desc += 1)
{
size_t count = (desc->vaddr_end - desc->vaddr_start + 1) >> TEST_GRANULE_POWER;
void *vstart = (void *)desc->vaddr_start;
void *pstart = (void *)desc->paddr_start;
LOG_I("v2p test on VA region [%016lx-%016lx]", vstart, desc->vaddr_end + 1);
int err_flag = 0;
for (size_t j = 0; j < count; j++, vstart += TEST_GRANULE_SIZE, pstart += TEST_GRANULE_SIZE)
{
void *pa = rt_hw_mmu_v2p(&mmu_info, vstart);
if ((desc->attr == MAPPED && pa != pstart) ||
(desc->attr == UNMAPPED && pa != 0))
err_flag = 1;
}
uassert_true(err_flag == 0);
}
}
// TODO use arrary for test region
#define MAP_PA ((void *)0xe0001000)
// test va recollection after unmap
static void test_find_vaddr_recol(void)
{
void *map;
map = rt_hw_mmu_map(&mmu_info, RT_NULL, MAP_PA, 4096, MMU_MAP_K_RWCB);
rt_hw_mmu_unmap(&mmu_info, map, 4096);
void *remap;
remap = rt_hw_mmu_map(&mmu_info, RT_NULL, MAP_PA, 4096, MMU_MAP_K_RWCB);
rt_hw_mmu_unmap(&mmu_info, map, 4096);
uassert_true(map == remap);
}
// find vaddr should return a valid VA for rt_hw_mmu_map
static void test_find_vaddr_valid(void)
{
size_t map;
map = (size_t)rt_hw_mmu_map(&mmu_info, RT_NULL, MAP_PA, 4096, MMU_MAP_K_RWCB);
rt_hw_mmu_unmap(&mmu_info, (void*)map, 4096);
LOG_I("Mapped pa %p to %p, %p", MAP_PA, map, mmu_info.vend);
uassert_true((map >= (mmu_info.vstart << 30)) && (map <= (((mmu_info.vend - mmu_info.vstart) ? mmu_info.vend : mmu_info.vend + 1) << 30)));
}
// ioremap functionality
static void test_ioremap(void)
{
}
static rt_err_t utest_tc_init(void)
{
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(test_v2p);
UTEST_UNIT_RUN(test_find_vaddr_recol);
UTEST_UNIT_RUN(test_find_vaddr_valid);
UTEST_UNIT_RUN(test_ioremap);
}
UTEST_TC_EXPORT(testcase, "testcases.libcpu.mmu", utest_tc_init, utest_tc_cleanup, 10);
#endif /* RT_USING_UTEST */
+9 -21
View File
@@ -13,6 +13,7 @@
#include <rtdevice.h>
#include "board.h"
#include "mm_aspace.h"
#include "tick.h"
#include "drv_uart.h"
@@ -31,8 +32,6 @@
rt_region_t init_page_region = {(rt_size_t)RT_HW_PAGE_START, (rt_size_t)RT_HW_PAGE_END};
rt_mmu_info mmu_info;
extern size_t MMUTable[];
struct mem_desc platform_mem_desc[] = {
@@ -43,24 +42,13 @@ struct mem_desc platform_mem_desc[] = {
#endif
void init_bss(void)
{
unsigned int *dst;
dst = &__bss_start;
while (dst < &__bss_end)
{
*dst++ = 0;
}
}
void primary_cpu_entry(void)
{
extern void entry(void);
/* disable global interrupt */
init_bss();
rt_hw_interrupt_disable();
entry();
}
@@ -69,14 +57,14 @@ void primary_cpu_entry(void)
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
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
+9 -4
View File
@@ -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
-1
View File
@@ -17,7 +17,6 @@
#include <mmu.h>
#include <ioremap.h>
extern rt_mmu_info mmu_info;
#endif
/* VirtIO */
+1
View File
@@ -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
+2 -1
View File
@@ -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
+5 -108
View File
@@ -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
+1
View File
@@ -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
+3 -2
View File
@@ -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
+1
View File
@@ -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
File diff suppressed because it is too large Load Diff
+3 -16
View File
@@ -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 */
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -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
+3 -16
View File
@@ -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 */
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -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();
+3 -16
View File
@@ -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 */
+1 -2
View File
@@ -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)
+18 -16
View File
@@ -8,16 +8,13 @@
* 2021-05-18 Jesven first version
*/
#include <rtthread.h>
#include <rthw.h>
#include <rtthread.h>
#ifdef ARCH_MM_MMU
#include <mmu.h>
#include <page.h>
#include <lwp_mm_area.h>
#include <lwp_user_mm.h>
#include <lwp_arch.h>
#include <lwp_user_mm.h>
extern size_t MMUTable[];
@@ -25,7 +22,7 @@ int arch_user_space_init(struct rt_lwp *lwp)
{
size_t *mmu_table;
mmu_table = (size_t*)rt_pages_alloc(0);
mmu_table = (size_t *)rt_pages_alloc(0);
if (!mmu_table)
{
return -1;
@@ -34,25 +31,28 @@ int arch_user_space_init(struct rt_lwp *lwp)
lwp->end_heap = USER_HEAP_VADDR;
memset(mmu_table, 0, ARCH_PAGE_SIZE);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, ARCH_PAGE_SIZE);
rt_hw_mmu_map_init(&lwp->mmu_info, (void*)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table, PV_OFFSET);
lwp->aspace = rt_aspace_create(
(void *)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table);
if (!lwp->aspace)
{
return -1;
}
return 0;
}
void *arch_kernel_mmu_table_get(void)
{
return (void*)NULL;
}
void arch_kuser_init(rt_mmu_info *mmu_info, void *vectors)
{
return (void *)NULL;
}
void arch_user_space_vtable_free(struct rt_lwp *lwp)
{
if (lwp && lwp->mmu_info.vtable)
if (lwp && lwp->aspace->page_table)
{
rt_pages_free(lwp->mmu_info.vtable, 0);
rt_pages_free(lwp->aspace->page_table, 0);
lwp->aspace->page_table = NULL;
}
}
@@ -62,9 +62,11 @@ int arch_expand_user_stack(void *addr)
size_t stack_addr = (size_t)addr;
stack_addr &= ~ARCH_PAGE_MASK;
if ((stack_addr >= (size_t)USER_STACK_VSTART) && (stack_addr < (size_t)USER_STACK_VEND))
if ((stack_addr >= (size_t)USER_STACK_VSTART) &&
(stack_addr < (size_t)USER_STACK_VEND))
{
void *map = lwp_map_user(lwp_self(), (void*)stack_addr, ARCH_PAGE_SIZE, 0);
void *map =
lwp_map_user(lwp_self(), (void *)stack_addr, ARCH_PAGE_SIZE, 0);
if (map || lwp_user_accessable(addr, 1))
{
+6 -5
View File
@@ -1,3 +1,4 @@
#include "mm_aspace.h"
#include <rtthread.h>
#include <stdint.h>
#include <string.h>
@@ -18,7 +19,7 @@ typedef struct
} Elf32_sym;
#ifdef ARCH_MM_MMU
void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf32_sym *dynsym)
void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf32_sym *dynsym)
{
size_t rel_off;
void* addr;
@@ -36,14 +37,14 @@ void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start,
memcpy(&v2, rel_dyn_start + rel_off + 4, 4);
*/
addr = rt_hw_mmu_v2p(m_info, (void*)((char*)rel_dyn_start + rel_off));
addr = rt_hw_mmu_v2p(aspace, (void*)((char*)rel_dyn_start + rel_off));
addr = (void*)((char*)addr - PV_OFFSET);
memcpy(&v1, addr, 4);
addr = rt_hw_mmu_v2p(m_info, (void*)((char*)rel_dyn_start + rel_off + 4));
addr = rt_hw_mmu_v2p(aspace, (void*)((char*)rel_dyn_start + rel_off + 4));
addr = (void*)((char*)addr - PV_OFFSET);
memcpy(&v2, addr, 4);
addr = rt_hw_mmu_v2p(m_info, (void*)((char*)text_start + v1));
addr = rt_hw_mmu_v2p(aspace, (void*)((char*)text_start + v1));
addr = (void*)((char*)addr - PV_OFFSET);
if ((v2 & 0xff) == R_ARM_RELATIVE)
{
@@ -69,7 +70,7 @@ void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start,
for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
{
//*got_item += (uint32_t)text_start;
addr = rt_hw_mmu_v2p(m_info, got_item);
addr = rt_hw_mmu_v2p(aspace, got_item);
addr = (void*)((char*)addr - PV_OFFSET);
*(uint32_t *)addr += (uint32_t)text_start;
}
+29 -21
View File
@@ -8,64 +8,72 @@
* 2019-10-28 Jesven first version
*/
#include <rtthread.h>
#include <rthw.h>
#include <rtthread.h>
#include <stddef.h>
#ifdef ARCH_MM_MMU
#include <mmu.h>
#include <page.h>
#include <lwp_mm_area.h>
#include <lwp_user_mm.h>
#include <lwp_arch.h>
#include <lwp_user_mm.h>
extern size_t MMUTable[];
#define KPTE_START (KERNEL_VADDR_START >> ARCH_SECTION_SHIFT)
int arch_user_space_init(struct rt_lwp *lwp)
{
size_t *mmu_table;
mmu_table = (size_t*)rt_pages_alloc(2);
mmu_table = (size_t *)rt_pages_alloc(2);
if (!mmu_table)
{
return -1;
}
lwp->end_heap = USER_HEAP_VADDR;
rt_memcpy(mmu_table + (KERNEL_VADDR_START >> ARCH_SECTION_SHIFT), MMUTable + (KERNEL_VADDR_START >> ARCH_SECTION_SHIFT), ARCH_PAGE_SIZE);
rt_memcpy(mmu_table + KPTE_START, (size_t *)rt_kernel_space.page_table + KPTE_START, ARCH_PAGE_SIZE);
rt_memset(mmu_table, 0, 3 * ARCH_PAGE_SIZE);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, 4 * ARCH_PAGE_SIZE);
rt_hw_mmu_map_init(&lwp->mmu_info, (void*)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table, PV_OFFSET);
lwp->aspace = rt_aspace_create((void *)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table);
if (!lwp->aspace)
{
return -1;
}
return 0;
}
void *arch_kernel_mmu_table_get(void)
{
return (void*)((char*)MMUTable + PV_OFFSET);
}
static struct rt_varea kuser_varea;
void arch_kuser_init(rt_mmu_info *mmu_info, void *vectors)
void arch_kuser_init(rt_aspace_t aspace, void *vectors)
{
const size_t kuser_size = 0x1000;
int err;
extern char __kuser_helper_start[], __kuser_helper_end[];
int kuser_sz = __kuser_helper_end - __kuser_helper_start;
rt_hw_mmu_map_auto(mmu_info, vectors, 0x1000, MMU_MAP_U_RO);
err = rt_aspace_map_static(aspace, &kuser_varea, &vectors, kuser_size,
MMU_MAP_U_RO, MMF_MAP_FIXED | MMF_PREFETCH,
&rt_mm_dummy_mapper, 0);
if (err != 0)
while (1)
; // early failed
rt_memcpy((void*)((char*)vectors + 0x1000 - kuser_sz), __kuser_helper_start, kuser_sz);
rt_memcpy((void *)((char *)vectors + 0x1000 - kuser_sz), __kuser_helper_start, kuser_sz);
/*
* vectors + 0xfe0 = __kuser_get_tls
* vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8
*/
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void*)((char*)vectors + 0x1000 - kuser_sz), kuser_sz);
rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, (void*)((char*)vectors + 0x1000 - kuser_sz), kuser_sz);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)((char *)vectors + 0x1000 - kuser_sz), kuser_sz);
rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, (void *)((char *)vectors + 0x1000 - kuser_sz), kuser_sz);
}
void arch_user_space_vtable_free(struct rt_lwp *lwp)
{
if (lwp && lwp->mmu_info.vtable)
if (lwp && lwp->aspace->page_table)
{
rt_pages_free(lwp->mmu_info.vtable, 2);
rt_pages_free(lwp->aspace->page_table, 2);
lwp->aspace->page_table = NULL;
}
}
@@ -77,7 +85,7 @@ int arch_expand_user_stack(void *addr)
stack_addr &= ~ARCH_PAGE_MASK;
if ((stack_addr >= (size_t)USER_STACK_VSTART) && (stack_addr < (size_t)USER_STACK_VEND))
{
void *map = lwp_map_user(lwp_self(), (void*)stack_addr, ARCH_PAGE_SIZE, 0);
void *map = lwp_map_user(lwp_self(), (void *)stack_addr, ARCH_PAGE_SIZE, 0);
if (map || lwp_user_accessable(addr, 1))
{
+18 -37
View File
@@ -15,42 +15,24 @@
* 2021-11-22 JasonHu add lwp_set_thread_context
* 2021-11-30 JasonHu add clone/fork support
*/
#include <rthw.h>
#include <rtthread.h>
#include <stddef.h>
#ifdef ARCH_MM_MMU
#include <mmu.h>
#include <page.h>
#include <lwp_mm_area.h>
#include <lwp_user_mm.h>
#include <lwp.h>
#include <lwp_arch.h>
#include <lwp_user_mm.h>
#include <page.h>
#include <stack.h>
#include <cpuport.h>
#include <encoding.h>
#include <stack.h>
extern rt_ubase_t MMUTable[];
int arch_expand_user_stack(void *addr)
{
int ret = 0;
rt_ubase_t stack_addr = (rt_ubase_t)addr;
stack_addr &= ~PAGE_OFFSET_MASK;
if ((stack_addr >= (rt_ubase_t)USER_STACK_VSTART) && (stack_addr < (rt_ubase_t)USER_STACK_VEND))
{
void *map = lwp_map_user(lwp_self(), (void *)stack_addr, PAGE_SIZE, RT_FALSE);
if (map || lwp_user_accessable(addr, 1))
{
ret = 1;
}
}
return ret;
}
void *lwp_copy_return_code_to_user_stack()
{
void lwp_thread_return();
@@ -68,13 +50,6 @@ void *lwp_copy_return_code_to_user_stack()
return RT_NULL;
}
rt_mmu_info *arch_kernel_get_mmu_info(void)
{
extern rt_mmu_info *mmu_info;
return mmu_info;
}
rt_ubase_t lwp_fix_sp(rt_ubase_t cursp)
{
void lwp_thread_return();
@@ -120,9 +95,14 @@ int arch_user_space_init(struct rt_lwp *lwp)
lwp->end_heap = USER_HEAP_VADDR;
rt_memcpy(mmu_table, MMUTable, PAGE_SIZE);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, 4 * PAGE_SIZE);
rt_hw_mmu_map_init(&lwp->mmu_info, (void *)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, (rt_size_t *)mmu_table, 0);
rt_memcpy(mmu_table, MMUTable, ARCH_PAGE_SIZE);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, ARCH_PAGE_SIZE);
lwp->aspace = rt_aspace_create(
(void *)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table);
if (!lwp->aspace)
{
return -1;
}
return 0;
}
@@ -134,9 +114,10 @@ void *arch_kernel_mmu_table_get(void)
void arch_user_space_vtable_free(struct rt_lwp *lwp)
{
if (lwp && lwp->mmu_info.vtable)
if (lwp && lwp->aspace->page_table)
{
rt_pages_free(lwp->mmu_info.vtable, 0);
rt_pages_free(lwp->aspace->page_table, 0);
lwp->aspace->page_table = NULL;
}
}
@@ -253,7 +234,7 @@ int arch_set_thread_context(void (*exit)(void), void *new_thread_stack,
*/
void lwp_exec_user(void *args, void *kernel_stack, void *user_entry)
{
arch_start_umode(args, user_entry, (void*)USER_STACK_VEND, kernel_stack);
arch_start_umode(args, user_entry, (void *)USER_STACK_VEND, kernel_stack);
}
void *arch_get_usp_from_uctx(struct rt_user_context *uctx)
+3 -6
View File
@@ -10,9 +10,9 @@
#ifndef LWP_ARCH_H__
#define LWP_ARCH_H__
#include <rthw.h>
#include <lwp.h>
#include <lwp_arch_comm.h>
#include <riscv_mmu.h>
#ifdef ARCH_MM_MMU
@@ -30,7 +30,7 @@
#define USER_HEAP_VEND 0xffffffffffff0000UL
#define USER_STACK_VSTART 0x270000000UL
#define USER_STACK_VEND USER_HEAP_VADDR
#define USER_VADDR_START 0x100000000UL
#define USER_VADDR_START 0x200000000UL
#define USER_VADDR_TOP 0xfffffffffffff000UL
#define USER_LOAD_VADDR 0x200000000
#define LDSO_LOAD_VADDR 0x200000000
@@ -49,9 +49,6 @@
extern "C" {
#endif
rt_mmu_info* arch_kernel_get_mmu_info(void);
int arch_expand_user_stack(void *addr);
rt_inline unsigned long rt_hw_ffz(unsigned long x)
{
return __builtin_ffsl(~x) - 1;
@@ -59,7 +56,7 @@ rt_inline unsigned long rt_hw_ffz(unsigned long x)
rt_inline void icache_invalid_all(void)
{
//TODO:
rt_hw_cpu_icache_invalidate_all();
}
#ifdef __cplusplus
+6 -5
View File
@@ -1,3 +1,4 @@
#include "mm_aspace.h"
#include <rtthread.h>
#include <stdint.h>
#include <string.h>
@@ -18,7 +19,7 @@ typedef struct
} Elf64_sym;
#ifdef ARCH_MM_MMU
void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf64_sym *dynsym)
void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf64_sym *dynsym)
{
size_t rel_off;
void* addr;
@@ -31,12 +32,12 @@ void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start,
{
uint32_t v1, v2;
addr = rt_hw_mmu_v2p(m_info, (void *)(((rt_size_t)rel_dyn_start) + rel_off));
addr = rt_hw_mmu_v2p(aspace, (void *)(((rt_size_t)rel_dyn_start) + rel_off));
memcpy(&v1, addr, 4);
addr = rt_hw_mmu_v2p(m_info, (void *)(((rt_size_t)rel_dyn_start) + rel_off + 4));
addr = rt_hw_mmu_v2p(aspace, (void *)(((rt_size_t)rel_dyn_start) + rel_off + 4));
memcpy(&v2, addr, 4);
addr = rt_hw_mmu_v2p(m_info, (void *)((rt_size_t)text_start + v1));
addr = rt_hw_mmu_v2p(aspace, (void *)((rt_size_t)text_start + v1));
if ((v2 & 0xff) == R_ARM_RELATIVE)
{
*(rt_size_t*)addr += (rt_size_t)text_start;
@@ -58,7 +59,7 @@ void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start,
for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
{
addr = rt_hw_mmu_v2p(m_info, got_item);
addr = rt_hw_mmu_v2p(aspace, got_item);
*(rt_size_t *)addr += (rt_size_t)text_start;
}
}
+33 -39
View File
@@ -12,33 +12,40 @@
#include <ioremap.h>
#ifdef ARCH_MM_MMU
#ifdef RT_USING_SMART
#include <mmu.h>
#include <lwp_mm_area.h>
#include <lwp_mm.h>
#include <mm_aspace.h>
static struct lwp_avl_struct *k_map_area;
extern rt_mmu_info mmu_info;
#define DBG_TAG "mm.ioremap"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
static void _iounmap_range(void *addr, size_t size)
enum ioremap_type
{
void *va = RT_NULL, *pa = RT_NULL;
int i = 0;
MM_AREA_TYPE_PHY,
MM_AREA_TYPE_PHY_CACHED
};
for (va = addr, i = 0; i < size; va = (void *)((char *)va + ARCH_PAGE_SIZE), i += ARCH_PAGE_SIZE)
{
pa = rt_hw_mmu_v2p(&mmu_info, va);
if (pa)
{
rt_hw_mmu_unmap(&mmu_info, va, ARCH_PAGE_SIZE);
}
}
}
void *rt_ioremap_start;
size_t rt_ioremap_size;
static void *_ioremap_type(void *paddr, size_t size, int type)
static void *_ioremap_type(void *paddr, size_t size, enum ioremap_type type)
{
void *v_addr = NULL;
size_t attr;
size_t lo_off;
int err;
lo_off = (uintptr_t)paddr & ARCH_PAGE_MASK;
struct rt_mm_va_hint hint = {
.prefer = ARCH_MAP_FAILED,
.map_size = RT_ALIGN(size + lo_off, ARCH_PAGE_SIZE),
.flags = 0,
.limit_start = rt_ioremap_start,
.limit_range_size = rt_ioremap_size,
};
switch (type)
{
@@ -51,19 +58,17 @@ static void *_ioremap_type(void *paddr, size_t size, int type)
default:
return v_addr;
}
err = rt_aspace_map_phy(&rt_kernel_space, &hint, attr, MM_PA_TO_OFF(paddr), &v_addr);
rt_mm_lock();
v_addr = rt_hw_mmu_map(&mmu_info, 0, paddr, size, attr);
if (v_addr)
if (err)
{
int ret = lwp_map_area_insert(&k_map_area, (size_t)v_addr, size, type);
if (ret != 0)
{
_iounmap_range(v_addr, size);
v_addr = NULL;
}
LOG_W("IOREMAP 0x%lx failed", paddr);
v_addr = NULL;
}
else
{
v_addr = v_addr + lo_off;
}
rt_mm_unlock();
return v_addr;
}
@@ -84,18 +89,7 @@ void *rt_ioremap_cached(void *paddr, size_t size)
void rt_iounmap(volatile void *vaddr)
{
struct lwp_avl_struct *ma_avl_node;
rt_mm_lock();
ma_avl_node = lwp_map_find(k_map_area, (size_t)vaddr);
if (ma_avl_node)
{
struct rt_mm_area_struct *ma = (struct rt_mm_area_struct *)ma_avl_node->data;
_iounmap_range((void *)ma->addr, ma->size);
lwp_map_area_remove(&k_map_area, (size_t)vaddr);
}
rt_mm_unlock();
rt_aspace_unmap(&rt_kernel_space, (void *)vaddr, 1);
}
#else
+5
View File
@@ -10,6 +10,8 @@
#ifndef __IOREMAP_H__
#define __IOREMAP_H__
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -19,6 +21,9 @@ void *rt_ioremap_nocache(void *paddr, size_t size);
void *rt_ioremap_cached (void *paddr, size_t size);
void rt_iounmap(volatile void *addr);
extern void *rt_ioremap_start;
extern size_t rt_ioremap_size;
#ifdef __cplusplus
}
#endif
+8 -10
View File
@@ -37,7 +37,6 @@
#include <rtdbg.h>
#ifdef ARCH_MM_MMU
#include <lwp_mm_area.h>
#include <lwp_user_mm.h>
#endif /* end of ARCH_MM_MMU */
@@ -183,7 +182,7 @@ struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **argv, char
return RT_NULL;
}
args_k = (size_t *)rt_hw_mmu_v2p(&lwp->mmu_info, args);
args_k = (size_t *)lwp_v2p(lwp, args);
args_k = (size_t *)((size_t)args_k - PV_OFFSET);
/* argc, argv[], 0, envp[], 0 , aux[] */
@@ -511,7 +510,6 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
void *pa, *va;
void *va_self;
rt_mmu_info *m_info = &lwp->mmu_info;
#endif
if (len < sizeof eheader)
@@ -613,7 +611,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
LOG_E("lwp map user failed!");
return -RT_ERROR;
}
pa = rt_hw_mmu_v2p(m_info, va);
pa = lwp_v2p(lwp, va);
process_header = (uint8_t *)pa - PV_OFFSET;
#else
process_header = (uint8_t *)rt_malloc(process_header_size + sizeof(char[16]));
@@ -646,7 +644,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
random = (uint8_t *)(USER_VADDR_TOP - ARCH_PAGE_SIZE - sizeof(char[16]));
krandom = (uint8_t *)rt_hw_mmu_v2p(m_info, random);
krandom = (uint8_t *)lwp_v2p(lwp, random);
krandom = (uint8_t *)krandom - PV_OFFSET;
rt_memcpy(krandom, &random_value, sizeof random_value);
#else
@@ -738,7 +736,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
{
if (user_area[i].size != 0)
{
va = lwp_map_user(lwp, user_area[i].start, user_area[i].size, (int)(i == 0));
va = lwp_map_user(lwp, user_area[i].start, user_area[i].size, (i == 0));
if (!va || (va != user_area[i].start))
{
result = -RT_ERROR;
@@ -836,7 +834,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
read_len = 0;
while (size)
{
pa = rt_hw_mmu_v2p(m_info, va);
pa = lwp_v2p(lwp, va);
va_self = (void *)((char *)pa - PV_OFFSET);
LOG_D("va_self = %p pa = %p", va_self, pa);
tmp_len = (size < ARCH_PAGE_SIZE) ? size : ARCH_PAGE_SIZE;
@@ -864,7 +862,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
while (size)
{
size_s = (size < ARCH_PAGE_SIZE - off) ? size : ARCH_PAGE_SIZE - off;
pa = rt_hw_mmu_v2p(m_info, va);
pa = lwp_v2p(lwp, va);
va_self = (void *)((char *)pa - PV_OFFSET);
memset((void *)((char *)va_self + off), 0, size_s);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)((char *)va_self + off), size_s);
@@ -942,7 +940,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
check_read(read_len, dynsym_size);
}
#ifdef ARCH_MM_MMU
arch_elf_reloc(m_info, (void *)load_off, rel_dyn_start, rel_dyn_size, got_start, got_size, dynsym);
arch_elf_reloc(lwp->aspace, (void *)load_off, rel_dyn_start, rel_dyn_size, got_start, got_size, dynsym);
#else
arch_elf_reloc((void *)load_off, rel_dyn_start, rel_dyn_size, got_start, got_size, dynsym);
@@ -1151,7 +1149,7 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
return -ENOMEM;
}
#ifdef ARCH_MM_MMU
if (lwp_user_space_init(lwp) != 0)
if (lwp_user_space_init(lwp, 0) != 0)
{
lwp_tid_put(tid);
lwp_ref_dec(lwp);
+10 -3
View File
@@ -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);
+6 -2
View File
@@ -10,7 +10,9 @@
#ifndef __LWP_ARCH_COMM__
#define __LWP_ARCH_COMM__
#include <mm_aspace.h>
#include <rtthread.h>
#include <mmu.h>
/**
* APIs that must port to all architectures
@@ -24,7 +26,9 @@ void arch_ret_to_user();
/* ELF relocation */
#ifdef ARCH_MM_MMU
void arch_elf_reloc(rt_mmu_info *m_info, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, void *dynsym);
struct rt_lwp;
void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, void *dynsym);
#else
void arch_elf_reloc(void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, void *dynsym);
#endif
@@ -42,7 +46,7 @@ void *arch_get_user_sp(void);
int arch_user_space_init(struct rt_lwp *lwp);
void arch_user_space_vtable_free(struct rt_lwp *lwp);
void *arch_kernel_mmu_table_get(void);
void arch_kuser_init(rt_mmu_info *mmu_info, void *vectors);
void arch_kuser_init(rt_aspace_t aspace, void *vectors);
int arch_expand_user_stack(void *addr);
/* thread id register */
-122
View File
@@ -1,122 +0,0 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-10-28 Jesven first version
*/
#include <rtthread.h>
#ifdef ARCH_MM_MMU
#include <lwp_mm_area.h>
int lwp_map_area_insert(struct lwp_avl_struct **avl_tree, size_t addr, size_t size, int ma_type)
{
struct lwp_avl_struct *node = RT_NULL;
struct rt_mm_area_struct *ma = RT_NULL;
if (!size)
{
return -1;
}
ma = (struct rt_mm_area_struct *)rt_malloc(sizeof(struct rt_mm_area_struct));
if (!ma)
{
return -1;
}
ma->addr = addr;
ma->size = size;
ma->type = ma_type;
node = (struct lwp_avl_struct *)rt_malloc(sizeof(struct lwp_avl_struct));
if (!node)
{
rt_free(ma);
return -1;
}
memset(node, 0, sizeof(struct lwp_avl_struct));
node->avl_key = ma->addr;
node->data = (void *)ma;
lwp_avl_insert(node, avl_tree);
return 0;
}
void lwp_map_area_remove(struct lwp_avl_struct **avl_tree, size_t addr)
{
struct lwp_avl_struct *node = RT_NULL;
node = lwp_avl_find(addr, *avl_tree);
if (!node)
{
return;
}
lwp_avl_remove(node, avl_tree);
rt_free(node->data);
rt_free(node);
}
struct lwp_avl_struct* lwp_map_find(struct lwp_avl_struct* ptree, size_t addr)
{
struct lwp_avl_struct *node = ptree;
while (1)
{
if (!node)
{
return node;
}
if ((size_t)node->avl_key <= addr)
{
struct rt_mm_area_struct *ma = (struct rt_mm_area_struct *)node->data;
if ((ma->addr <= addr) && (addr < ma->addr + ma->size))
{
/* find area */
break;
}
node = node->avl_right;
}
else
{
node = node->avl_left;
}
}
return node;
}
struct lwp_avl_struct* lwp_map_find_first(struct lwp_avl_struct* ptree)
{
if (ptree == AVL_EMPTY)
{
return (struct lwp_avl_struct *)0;
}
while (1)
{
if (!ptree->avl_left)
{
break;
}
ptree = ptree->avl_left;
}
return ptree;
}
int top_mem_fun(struct lwp_avl_struct* ptree, void *arg)
{
size_t *vs = (size_t *)arg;
struct rt_mm_area_struct *ma;
ma = (struct rt_mm_area_struct *)ptree->data;
*vs += ma->size;
return 0;
}
size_t lwp_vmem_count(struct lwp_avl_struct *ptree)
{
size_t vsize = 0;
lwp_avl_traversal(ptree, top_mem_fun, &vsize);
return vsize;
}
#endif
-53
View File
@@ -1,53 +0,0 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-10-28 Jesven first version
*/
#ifndef __LWP_MM_AREA_H__
#define __LWP_MM_AREA_H__
#include <string.h>
#include <stdint.h>
#include <lwp_avl.h>
#ifdef ARCH_MM_MMU
#ifdef __cplusplus
extern "C" {
#endif
enum
{
MM_AREA_TYPE_PHY = 0, /* mm_area physical address is IO register or reserved memory no cached*/
MM_AREA_TYPE_PHY_CACHED, /* mm_area physical address is IO register or reserved memory with cached */
MM_AREA_TYPE_SHM, /* mm_area physical address is shared memory */
MM_AREA_TYPE_DATA, /* mm_area physical address is alloced from page manager for data */
MM_AREA_TYPE_TEXT, /* mm_area physical address is alloced from page manager for text */
MM_AREA_TYPE_UNKNOW,
};
struct rt_mm_area_struct
{
size_t addr;
size_t size;
int type;
};
int lwp_map_area_insert(struct lwp_avl_struct **avl_tree, size_t addr, size_t size, int ma_type);
void lwp_map_area_remove(struct lwp_avl_struct **avl_tree, size_t addr);
struct lwp_avl_struct* lwp_map_find(struct lwp_avl_struct* ptree, size_t addr);
struct lwp_avl_struct* lwp_map_find_first(struct lwp_avl_struct* ptree);
size_t lwp_vmem_count(struct lwp_avl_struct *ptree);
#ifdef __cplusplus
}
#endif
#endif
#endif /*__LWP_MM_AREA_H__*/
+59 -14
View File
@@ -15,12 +15,15 @@
#include <lwp_shm.h>
#include <lwp_mm.h>
#include <lwp_mm_area.h>
#include <lwp_user_mm.h>
#include <mmu.h>
#include <mm_aspace.h>
#include <mm_flag.h>
/* the kernel structure to represent a share-memory */
struct lwp_shm_struct
{
struct rt_mem_obj mem_obj;
size_t addr; /* point to the next item in the free list when not used */
size_t size;
int ref;
@@ -34,6 +37,35 @@ static int shm_free_list = -1; /* the single-direct list of freed items */
static int shm_id_used = 0; /* the latest allocated item in the array */
static struct lwp_shm_struct _shm_ary[RT_LWP_SHM_MAX_NR];
static const char *get_shm_name(rt_varea_t varea)
{
return "user.shm";
}
static void on_shm_varea_open(struct rt_varea *varea)
{
struct lwp_shm_struct *shm;
shm = rt_container_of(varea->mem_obj, struct lwp_shm_struct, mem_obj);
shm->ref += 1;
}
static void on_shm_varea_close(struct rt_varea *varea)
{
struct lwp_shm_struct *shm;
shm = rt_container_of(varea->mem_obj, struct lwp_shm_struct, mem_obj);
shm->ref -= 1;
}
static void on_shm_page_fault(struct rt_varea *varea, struct rt_mm_fault_msg *msg)
{
struct lwp_shm_struct *shm;
shm = rt_container_of(varea->mem_obj, struct lwp_shm_struct, mem_obj);
msg->response.status = MM_FAULT_STATUS_OK;
msg->response.vaddr = (void *)shm->addr;
msg->response.size = shm->size;
return ;
}
/*
* Try to allocate an structure 'lwp_shm_struct' from the freed list or the
* static array.
@@ -110,6 +142,12 @@ static int _lwp_shmget(size_t key, size_t size, int create)
p->size = (1UL << (bit + ARCH_PAGE_SHIFT));
p->ref = 0;
p->key = key;
p->mem_obj.get_name = get_shm_name;
p->mem_obj.on_page_fault = on_shm_page_fault;
p->mem_obj.on_varea_open = on_shm_varea_open;
p->mem_obj.on_varea_close = on_shm_varea_close;
p->mem_obj.hint_free = NULL;
p->mem_obj.on_page_offload = NULL;
/* then insert it into the balancing binary tree */
node_key = (struct lwp_avl_struct *)rt_malloc(sizeof(struct lwp_avl_struct) * 2);
@@ -212,15 +250,15 @@ int lwp_shmrm(int id)
{
int ret = 0;
rt_mm_lock();
ret = _lwp_shmrm(id);
rt_mm_unlock();
return ret;
}
/* Map the shared memory specified by 'id' to the specified virtual address. */
static void *_lwp_shmat(int id, void *shm_vaddr)
{
int err;
struct rt_lwp *lwp = RT_NULL;
struct lwp_avl_struct *node_key = RT_NULL;
struct lwp_shm_struct *p = RT_NULL;
@@ -244,10 +282,16 @@ static void *_lwp_shmat(int id, void *shm_vaddr)
{
return RT_NULL;
}
va = lwp_map_user_type(lwp, shm_vaddr, (void *)p->addr, p->size, 1, MM_AREA_TYPE_SHM);
if (va)
if (shm_vaddr == 0)
va = ARCH_MAP_FAILED;
else
va = shm_vaddr;
err = rt_aspace_map(lwp->aspace, &va, p->size, MMU_MAP_U_RWCB, MMF_PREFETCH,
&p->mem_obj, 0);
if (err != RT_EOK)
{
p->ref++;
va = 0;
}
return va;
}
@@ -261,9 +305,9 @@ void *lwp_shmat(int id, void *shm_vaddr)
{
return RT_NULL;
}
rt_mm_lock();
ret = _lwp_shmat(id, shm_vaddr);
rt_mm_unlock();
return ret;
}
@@ -276,7 +320,7 @@ static struct lwp_shm_struct *_lwp_shm_struct_get(struct rt_lwp *lwp, void *shm_
{
return RT_NULL;
}
pa = rt_hw_mmu_v2p(&lwp->mmu_info, shm_vaddr); /* physical memory */
pa = lwp_v2p(lwp, shm_vaddr); /* physical memory */
node_pa = lwp_avl_find((size_t)pa, shm_tree_pa);
if (!node_pa)
@@ -343,14 +387,15 @@ int _lwp_shmdt(void *shm_vaddr)
{
return -1;
}
ret = _lwp_shm_ref_dec(lwp, shm_vaddr);
if (ret >= 0)
ret = rt_aspace_unmap(lwp->aspace, shm_vaddr, 1);
if (ret != RT_EOK)
{
lwp_unmap_user_phy(lwp, shm_vaddr);
return 0;
ret = -1;
}
return -1;
return ret;
}
/* A wrapping function: detach the mapped shared memory. */
int lwp_shmdt(void *shm_vaddr)
{
+20 -12
View File
@@ -13,8 +13,11 @@
*/
#define _GNU_SOURCE
/* RT-Thread System call */
#include <rtthread.h>
#include <rthw.h>
#include <board.h>
#include <mm_aspace.h>
#include <string.h>
#include <lwp.h>
#ifdef ARCH_MM_MMU
@@ -1282,7 +1285,7 @@ rt_err_t sys_timer_create(clockid_t clockid, struct sigevent *restrict sevp, tim
#ifdef ARCH_MM_MMU
struct sigevent sevp_k;
timer_t timerid_k;
struct sigevent evp_default;
if (sevp == NULL)
{
sevp_k.sigev_notify = SIGEV_SIGNAL;
@@ -1362,7 +1365,7 @@ rt_thread_t sys_thread_create(void *arg[])
lwp = rt_thread_self()->lwp;
lwp_ref_inc(lwp);
#ifdef ARCH_MM_MMU
user_stack = lwp_map_user(lwp, 0, (size_t)arg[3], 0);
user_stack = lwp_map_user(lwp, 0, (size_t)arg[3], 0);
if (!user_stack)
{
goto fail;
@@ -1605,11 +1608,15 @@ rt_weak long sys_clone(void *arg[])
return _sys_clone(arg);
}
int lwp_dup_user(struct lwp_avl_struct* ptree, void *arg);
int lwp_dup_user(rt_varea_t varea, void *arg);
static int _copy_process(struct rt_lwp *dest_lwp, struct rt_lwp *src_lwp)
{
return lwp_avl_traversal(src_lwp->map_area, lwp_dup_user, dest_lwp);
int err;
dest_lwp->lwp_obj->source = src_lwp->aspace;
err = rt_aspace_traversal(src_lwp->aspace, lwp_dup_user, dest_lwp);
dest_lwp->lwp_obj->source = NULL;
return err;
}
static void lwp_struct_copy(struct rt_lwp *dst, struct rt_lwp *src)
@@ -1694,7 +1701,7 @@ int _sys_fork(void)
}
/* user space init */
if (lwp_user_space_init(lwp) != 0)
if (lwp_user_space_init(lwp, 1) != 0)
{
SET_ERRNO(ENOMEM);
goto fail;
@@ -2302,7 +2309,7 @@ int sys_execve(const char *path, char *const argv[], char *const envp[])
rt_memset(new_lwp, 0, sizeof(struct rt_lwp));
new_lwp->ref = 1;
lwp_user_object_lock_init(new_lwp);
ret = arch_user_space_init(new_lwp);
ret = lwp_user_space_init(new_lwp, 0);
if (ret != 0)
{
SET_ERRNO(ENOMEM);
@@ -2371,8 +2378,9 @@ int sys_execve(const char *path, char *const argv[], char *const envp[])
rt_pages_free(page, 0);
#ifdef ARCH_MM_MMU
_swap_lwp_data(lwp, new_lwp, rt_mmu_info, mmu_info);
_swap_lwp_data(lwp, new_lwp, struct lwp_avl_struct *, map_area);
_swap_lwp_data(lwp, new_lwp, struct rt_aspace *, aspace);
_swap_lwp_data(lwp, new_lwp, struct rt_lwp_objs *, lwp_obj);
_swap_lwp_data(lwp, new_lwp, size_t, end_heap);
#endif
_swap_lwp_data(lwp, new_lwp, uint8_t, lwp_type);
@@ -2392,7 +2400,7 @@ int sys_execve(const char *path, char *const argv[], char *const envp[])
/* to do: clsoe files with flag CLOEXEC */
lwp_mmu_switch(thread);
lwp_aspace_switch(thread);
rt_hw_interrupt_enable(level);
@@ -4562,17 +4570,17 @@ const static void* func_table[] =
SYSCALL_USPACE(SYSCALL_SIGN(sys_madvise)),
SYSCALL_SIGN(sys_sched_setparam),
SYSCALL_SIGN(sys_sched_getparam),
SYSCALL_SIGN(sys_sched_get_priority_max),
SYSCALL_SIGN(sys_sched_get_priority_max), /* 150 */
SYSCALL_SIGN(sys_sched_get_priority_min),
SYSCALL_SIGN(sys_sched_setscheduler),
SYSCALL_SIGN(sys_sched_getscheduler),
SYSCALL_SIGN(sys_setaffinity),
SYSCALL_SIGN(sys_fsync),
SYSCALL_SIGN(sys_fsync), /* 155 */
SYSCALL_SIGN(sys_clock_nanosleep),
SYSCALL_SIGN(sys_timer_create),
SYSCALL_SIGN(sys_timer_delete),
SYSCALL_SIGN(sys_timer_settime),
SYSCALL_SIGN(sys_timer_gettime),
SYSCALL_SIGN(sys_timer_gettime), /* 160 */
SYSCALL_SIGN(sys_timer_getoverrun),
SYSCALL_SIGN(sys_mq_open),
SYSCALL_SIGN(sys_mq_unlink),
File diff suppressed because it is too large Load Diff
+23 -10
View File
@@ -16,24 +16,24 @@
#ifdef ARCH_MM_MMU
#include <lwp.h>
#include <lwp_mm_area.h>
#include <mmu.h>
#include <mm_aspace.h>
#include <mm_fault.h>
#include <mm_page.h>
#ifdef __cplusplus
extern "C" {
#endif
int lwp_user_space_init(struct rt_lwp *lwp);
int lwp_user_space_init(struct rt_lwp *lwp, rt_bool_t is_fork);
void lwp_unmap_user_space(struct rt_lwp *lwp);
int lwp_unmap_user(struct rt_lwp *lwp, void *va);
void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, int text);
void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, rt_bool_t text);
void *lwp_map_user_phy(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t map_size, int cached);
void *lwp_map_user_phy(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t map_size, rt_bool_t cached);
int lwp_unmap_user_phy(struct rt_lwp *lwp, void *va);
void *lwp_map_user_type(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t map_size, int cached, int type);
int lwp_unmap_user_type(struct rt_lwp *lwp, void *va);
rt_base_t lwp_brk(void *addr);
void* lwp_mmap2(void *addr, size_t length, int prot, int flags, int fd, off_t pgoffset);
int lwp_munmap(void *addr);
@@ -42,9 +42,22 @@ size_t lwp_get_from_user(void *dst, void *src, size_t size);
size_t lwp_put_to_user(void *dst, void *src, size_t size);
int lwp_user_accessable(void *addr, size_t size);
size_t lwp_data_get(rt_mmu_info *mmu_info, void *dst, void *src, size_t size);
size_t lwp_data_put(rt_mmu_info *mmu_info, void *dst, void *src, size_t size);
void lwp_data_cache_flush(rt_mmu_info *mmu_info, void *vaddr, size_t size);
size_t lwp_data_get(struct rt_lwp *lwp, void *dst, void *src, size_t size);
size_t lwp_data_put(struct rt_lwp *lwp, void *dst, void *src, size_t size);
void lwp_data_cache_flush(struct rt_lwp *lwp, void *vaddr, size_t size);
static inline void *_lwp_v2p(struct rt_lwp *lwp, void *vaddr)
{
return rt_hw_mmu_v2p(lwp->aspace, vaddr);
}
static inline void *lwp_v2p(struct rt_lwp *lwp, void *vaddr)
{
RD_LOCK(lwp->aspace);
void *paddr = _lwp_v2p(lwp, vaddr);
RD_UNLOCK(lwp->aspace);
return paddr;
}
#ifdef __cplusplus
}
File diff suppressed because it is too large Load Diff
+2 -26
View File
@@ -11,30 +11,6 @@
#ifndef __PAGE_H__
#define __PAGE_H__
#ifdef ARCH_MM_MMU
typedef struct tag_region
{
size_t start;
size_t end;
} rt_region_t;
void rt_page_init(rt_region_t reg);
void *rt_pages_alloc(uint32_t size_bits);
void rt_page_ref_inc(void *addr, uint32_t size_bits);
int rt_page_ref_get(void *addr, uint32_t size_bits);
int rt_pages_free(void *addr, uint32_t size_bits);
void rt_pageinfo_dump(void);
size_t rt_page_bits(size_t size);
void rt_page_get_info(size_t *total_nr, size_t *free_nr);
#endif
#include <mm_page.h>
#endif /*__PAGE_H__*/
+21
View File
@@ -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')
+178
View File
@@ -0,0 +1,178 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-14 WangXiaoyao the first version
*/
#include <rtdef.h>
#include <avl.h>
#include "avl_adpt.h"
#include "mm_aspace.h"
#include "mm_private.h"
#define DBG_TAG "MM"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
/**
* @brief Adapter Layer for lwp AVL BST
*/
rt_err_t _aspace_bst_init(struct rt_aspace *aspace)
{
aspace->tree.tree.root_node = AVL_ROOT;
return RT_EOK;
}
static int compare_overlap(void *as, void *ae, void *bs, void *be)
{
LOG_D("as %lx, ae %lx, bs %lx, be %lx", as, ae, bs, be);
int cmp;
if (as > be)
{
cmp = 1;
}
else if (ae < bs)
{
cmp = -1;
}
else
{
cmp = 0;
}
LOG_D("ret %d", cmp);
return cmp;
}
static int compare_exceed(void *as, void *ae, void *bs, void *be)
{
LOG_D("as %lx, ae %lx, bs %lx, be %lx", as, ae, bs, be);
int cmp;
if (as > bs)
{
cmp = 1;
}
else if (as < bs)
{
cmp = -1;
}
else
{
cmp = 0;
}
LOG_D("ret %d", cmp);
return cmp;
}
static struct rt_varea *search(struct util_avl_root *root,
struct _mm_range range,
int (*compare)(void *as, void *ae, void *bs,
void *be))
{
struct util_avl_struct *node = root->root_node;
while (node)
{
rt_varea_t varea = VAREA_ENTRY(node);
int cmp = compare(range.start, range.end, varea->start,
varea->start + varea->size - 1);
if (cmp < 0)
{
node = node->avl_left;
}
else if (cmp > 0)
{
node = node->avl_right;
}
else
{
return varea;
}
}
return NULL;
}
struct rt_varea *_aspace_bst_search(struct rt_aspace *aspace, void *key)
{
struct util_avl_root *root = &aspace->tree.tree;
struct _mm_range range = {key, key};
return search(root, range, compare_overlap);
}
rt_varea_t _aspace_bst_search_exceed(struct rt_aspace *aspace, void *start)
{
struct util_avl_root *root = &aspace->tree.tree;
struct util_avl_struct *node = root->root_node;
rt_varea_t closest = NULL;
ptrdiff_t min_off = PTRDIFF_MAX;
while (node)
{
rt_varea_t varea = VAREA_ENTRY(node);
void *va_s = varea->start;
int cmp = compare_exceed(start, start, va_s, va_s);
if (cmp < 0)
{
ptrdiff_t off = va_s - start;
if (off < min_off)
{
min_off = off;
closest = varea;
}
node = node->avl_left;
}
else if (cmp > 0)
{
node = node->avl_right;
}
else
{
return varea;
}
}
return closest;
}
struct rt_varea *_aspace_bst_search_overlap(struct rt_aspace *aspace,
struct _mm_range range)
{
struct util_avl_root *root = &aspace->tree.tree;
return search(root, range, compare_overlap);
}
void _aspace_bst_insert(struct rt_aspace *aspace, struct rt_varea *varea)
{
struct util_avl_root *root = &aspace->tree.tree;
struct util_avl_struct *current = NULL;
struct util_avl_struct **next = &(root->root_node);
rt_ubase_t key = (rt_ubase_t)varea->start;
/* Figure out where to put new node */
while (*next)
{
current = *next;
struct rt_varea *data = VAREA_ENTRY(current);
if (key < (rt_ubase_t)data->start)
next = &(current->avl_left);
else if (key > (rt_ubase_t)data->start)
next = &(current->avl_right);
else
return;
}
/* Add new node and rebalance tree. */
util_avl_link(&varea->node.node, current, next);
util_avl_rebalance(current, root);
return;
}
void _aspace_bst_remove(struct rt_aspace *aspace, struct rt_varea *varea)
{
struct util_avl_struct *node = &varea->node.node;
util_avl_remove(node, &aspace->tree.tree);
}
+37
View File
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-14 WangXiaoyao the first version
*/
#ifndef __MM_AVL_ADPT_H__
#define __MM_AVL_ADPT_H__
#include <avl.h>
#include <rtdef.h>
#include <rtthread.h>
#include <stdint.h>
#define VAREA_ENTRY(pnode) \
(pnode) \
? rt_container_of(rt_container_of(pnode, struct _aspace_node, node), \
struct rt_varea, node) \
: 0
#define ASPACE_VAREA_NEXT(pva) (VAREA_ENTRY(util_avl_next(&pva->node.node)))
#define ASPACE_VAREA_FIRST(aspace) (VAREA_ENTRY(util_avl_first(&aspace->tree.tree)))
typedef struct _aspace_node
{
struct util_avl_struct node;
} *_aspace_node_t;
typedef struct _aspace_tree
{
struct util_avl_root tree;
} *_aspace_tree_t;
#endif /* __MM_AVL_ADPT_H__ */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+135
View File
@@ -0,0 +1,135 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-12-06 WangXiaoyao the first version
*/
#include <rtthread.h>
#ifdef RT_USING_SMART
#include <lwp.h>
#include <lwp_syscall.h>
#include "mm_aspace.h"
#include "mm_fault.h"
#include "mm_flag.h"
#include "mm_private.h"
#include <mmu.h>
#include <tlb.h>
#define DBG_TAG "mm.fault"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#define UNRECOVERABLE 0
#define RECOVERABLE 1
static int _fetch_page(rt_varea_t varea, struct rt_mm_fault_msg *msg)
{
int err = UNRECOVERABLE;
varea->mem_obj->on_page_fault(varea, msg);
if (msg->response.status == MM_FAULT_STATUS_OK)
{
void *store = msg->response.vaddr;
rt_size_t store_sz = msg->response.size;
if (msg->vaddr + store_sz > varea->start + varea->size)
{
LOG_W("%s more size of buffer is provided than varea", __func__);
}
else
{
rt_hw_mmu_map(varea->aspace, msg->vaddr, store + PV_OFFSET,
store_sz, varea->attr);
rt_hw_tlb_invalidate_range(varea->aspace, msg->vaddr, store_sz,
ARCH_PAGE_SIZE);
err = RECOVERABLE;
}
}
return err;
}
static int _read_fault(rt_varea_t varea, void *pa, struct rt_mm_fault_msg *msg)
{
int err = UNRECOVERABLE;
if (msg->fault_type == MM_FAULT_TYPE_PAGE_FAULT)
{
RT_ASSERT(pa == ARCH_MAP_FAILED);
err = _fetch_page(varea, msg);
}
else
{
/* signal a fault to user? */
}
return err;
}
static int _write_fault(rt_varea_t varea, void *pa, struct rt_mm_fault_msg *msg)
{
int err = UNRECOVERABLE;
if (msg->fault_type == MM_FAULT_TYPE_PAGE_FAULT)
{
RT_ASSERT(pa == ARCH_MAP_FAILED);
err = _fetch_page(varea, msg);
}
else if (msg->fault_type == MM_FAULT_TYPE_ACCESS_FAULT &&
varea->flag & MMF_COW)
{
}
else
{
/* signal a fault to user? */
}
return err;
}
static int _exec_fault(rt_varea_t varea, void *pa, struct rt_mm_fault_msg *msg)
{
int err = UNRECOVERABLE;
if (msg->fault_type == MM_FAULT_TYPE_PAGE_FAULT)
{
RT_ASSERT(pa == ARCH_MAP_FAILED);
err = _fetch_page(varea, msg);
}
return err;
}
int rt_mm_fault_try_fix(struct rt_mm_fault_msg *msg)
{
struct rt_lwp *lwp = lwp_self();
int err = UNRECOVERABLE;
uintptr_t va = (uintptr_t)msg->vaddr;
va &= ~ARCH_PAGE_MASK;
msg->vaddr = (void *)va;
if (lwp)
{
rt_aspace_t aspace = lwp->aspace;
rt_varea_t varea = _aspace_bst_search(aspace, msg->vaddr);
if (varea)
{
void *pa = rt_hw_mmu_v2p(aspace, msg->vaddr);
msg->off = (msg->vaddr - varea->start) >> ARCH_PAGE_SHIFT;
/* permission checked by fault op */
switch (msg->fault_op)
{
case MM_FAULT_OP_READ:
err = _read_fault(varea, pa, msg);
break;
case MM_FAULT_OP_WRITE:
err = _write_fault(varea, pa, msg);
break;
case MM_FAULT_OP_EXECUTE:
err = _exec_fault(varea, pa, msg);
break;
}
}
}
return err;
}
#endif /* RT_USING_SMART */
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-12-06 WangXiaoyao the first version
*/
#ifndef __MM_FAULT_H__
#define __MM_FAULT_H__
#include <rtthread.h>
#include <stddef.h>
#include <stdint.h>
#define MM_FAULT_STATUS_OK 0
#define MM_FAULT_STATUS_UNRECOVERABLE 1
struct rt_mm_fault_res
{
void *vaddr;
rt_size_t size;
int status;
};
enum rt_mm_fault_op
{
MM_FAULT_OP_READ = 1,
MM_FAULT_OP_WRITE,
MM_FAULT_OP_EXECUTE,
};
enum rt_mm_fault_type
{
MM_FAULT_TYPE_ACCESS_FAULT,
MM_FAULT_TYPE_PAGE_FAULT,
MM_FAULT_TYPE_BUS_ERROR,
MM_FAULT_TYPE_GENERIC,
};
struct rt_mm_fault_msg
{
enum rt_mm_fault_op fault_op;
enum rt_mm_fault_type fault_type;
rt_size_t off;
void *vaddr;
struct rt_mm_fault_res response;
};
/* MMU base page fault handler, return 1 is */
int rt_mm_fault_try_fix(struct rt_mm_fault_msg *msg);
#endif /* __MM_FAULT_H__ */
+89
View File
@@ -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__ */
+109
View File
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-30 WangXiaoyao the first version
*/
#include <rtthread.h>
#include "mm_aspace.h"
#include "mm_fault.h"
#include "mm_page.h"
#include <mmu.h>
#define DBG_TAG "mm.object"
#define DBG_LVL DBG_INFO
#include "rtdbg.h"
static const char *get_name(rt_varea_t varea)
{
return "dummy-mapper";
}
void rt_varea_insert_page(rt_varea_t varea, void *page_addr)
{
rt_page_t page = rt_page_addr2page(page_addr);
if (varea->frames == NULL)
{
varea->frames = page;
page->next = NULL;
}
else
{
varea->frames->pre = page;
page->next = varea->frames;
varea->frames = page;
}
}
void rt_varea_free_pages(rt_varea_t varea)
{
rt_page_t page = varea->frames;
while (page)
{
rt_page_t next = page->next;
void *pg_va = rt_page_page2addr(page);
rt_pages_free(pg_va, 0);
page = next;
}
}
void rt_varea_offload_page(rt_varea_t varea, void *vaddr, rt_size_t size)
{
void *vend = vaddr + size;
while (vaddr != vend)
{
rt_page_t page = rt_page_addr2page(vaddr);
page->pre->next = page->next;
page->next->pre = page->pre;
rt_pages_free(vaddr, 0);
vaddr += ARCH_PAGE_SIZE;
}
}
static void on_page_fault(struct rt_varea *varea, struct rt_mm_fault_msg *msg)
{
void *page;
page = rt_pages_alloc(0);
if (!page)
{
LOG_W("%s: page alloc failed", __func__);
return;
}
msg->response.status = MM_FAULT_STATUS_OK;
msg->response.size = ARCH_PAGE_SIZE;
msg->response.vaddr = page;
rt_varea_insert_page(varea, page);
}
static void on_varea_open(struct rt_varea *varea)
{
varea->data = NULL;
}
static void on_varea_close(struct rt_varea *varea)
{
}
static void on_page_offload(rt_varea_t varea, void *vaddr, rt_size_t size)
{
rt_varea_offload_page(varea, vaddr, size);
}
struct rt_mem_obj rt_mm_dummy_mapper = {
.get_name = get_name,
.on_page_fault = on_page_fault,
.hint_free = NULL,
.on_varea_open = on_varea_open,
.on_varea_close = on_varea_close,
.on_page_offload = on_page_offload,
};
File diff suppressed because it is too large Load Diff
+81
View File
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-11-01 Jesven The first version
* 2022-12-13 WangXiaoyao Hot-pluggable, extensible
* page management algorithm
*/
#ifndef __MM_PAGE_H__
#define __MM_PAGE_H__
#include <rthw.h>
#include <rtthread.h>
#include <stdint.h>
#define GET_FLOOR(type) \
(1ul << (8 * sizeof(rt_size_t) - __builtin_clzl(2 * sizeof(type) - 1) - 1))
#define DEF_PAGE_T(fields) \
typedef struct rt_page {\
union {struct {fields}; char _padding[GET_FLOOR(struct {fields})];};\
} *rt_page_t
DEF_PAGE_T(
struct rt_page *next; /* same level next */
struct rt_page *pre; /* same level pre */
rt_uint32_t size_bits; /* if is ARCH_ADDRESS_WIDTH_BITS, means not free */
rt_uint32_t ref_cnt; /* page group ref count */
);
#undef GET_FLOOR
#undef DEF_PAGE_T
typedef struct tag_region
{
rt_size_t start;
rt_size_t end;
} rt_region_t;
extern const rt_size_t rt_mpr_size;
extern void *rt_mpr_start;
void rt_page_init(rt_region_t reg);
void rt_page_cleanup(void);
void *rt_pages_alloc(rt_uint32_t size_bits);
void rt_page_ref_inc(void *addr, rt_uint32_t size_bits);
int rt_page_ref_get(void *addr, rt_uint32_t size_bits);
int rt_pages_free(void *addr, rt_uint32_t size_bits);
void rt_page_list(void);
rt_size_t rt_page_bits(rt_size_t size);
void rt_page_get_info(rt_size_t *total_nr, rt_size_t *free_nr);
void *rt_page_page2addr(struct rt_page *p);
struct rt_page *rt_page_addr2page(void *addr);
/**
* @brief Install page frames at run-time
* Region size must be aligned to 2^(RT_PAGE_MAX_ORDER + ARCH_PAGE_SHIFT - 1)
* bytes currently (typically 2 MB).
*
* !WARNING this API will NOT check whether region is valid or not in list
*
* @param region region.start as first page frame(inclusive),
* region.end as first page frame after free region
* @return int 0 on success
*/
int rt_page_install(rt_region_t region);
#endif /* __MM_PAGE_H__ */
+94
View File
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-14 WangXiaoyao the first version
*/
#ifndef __MM_INTERN_H__
#define __MM_INTERN_H__
#include "mm_aspace.h"
#include <rtdef.h>
#include <stddef.h>
/**
* @brief DATA STRUCTURE & API USED INTERNALLY
*
* This is mainly a wrapper layer to actual data structure.
* In this way, we can switch to any BST we like by adding new
* wrapper code.
* Every BST must satisfy the API to support MM
*
* *INFO: varea range convention
* For API, a range is specified by a base and its length.
* This provides a clear interface without ambiguity.
* For implementation, a range is specified by [start, end] tuple
* where both start and end are inclusive.
*/
struct _mm_range
{
void *start;
void *end;
};
/**
* @brief
*
* @param aspace
* @return rt_err_t
*/
rt_err_t _aspace_bst_init(struct rt_aspace *aspace);
/**
* @brief
*
* @param aspace
* @param start
* @return struct rt_varea*
*/
struct rt_varea *_aspace_bst_search(struct rt_aspace *aspace, void *start);
/**
* @brief Retrieve lowest varea satisfies
* ((varea->start >= start) || (varea->end >= start))
*
* @param aspace
* @param length
* @param struct _mm_range
* @return struct rt_varea*
*/
struct rt_varea *_aspace_bst_search_exceed(struct rt_aspace *aspace,
void *start);
/**
* @brief Retrieve any varea overlaps a specified address range
*
* @param aspace
* @param start
* @param length
* @return struct rt_varea*
*/
struct rt_varea *_aspace_bst_search_overlap(struct rt_aspace *aspace,
struct _mm_range range);
/**
* @brief Insert a varea into the bst
*
* @param aspace
* @param varea
*/
void _aspace_bst_insert(struct rt_aspace *aspace, struct rt_varea *varea);
/**
* @brief Remove a varea from the bst
*
* @param aspace
* @param varea
*/
void _aspace_bst_remove(struct rt_aspace *aspace, struct rt_varea *varea);
#endif /* __MM_INTERN_H__ */
+8
View File
@@ -0,0 +1,8 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('ADT', src, depend = [], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
+116
View File
@@ -0,0 +1,116 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-10-12 Jesven first version
* 2022-11-14 WangXiaoyao Optimize for generic use case
* and performance
*/
#ifndef __UTIL_TREE_AVL_H__
#define __UTIL_TREE_AVL_H__
#include <rtdef.h>
#include <stdint.h>
struct util_avl_struct
{
struct util_avl_struct *avl_left;
struct util_avl_struct *avl_right;
struct util_avl_struct *parent;
size_t height;
};
#define AVL_ROOT ((struct util_avl_struct *)0)
struct util_avl_root
{
struct util_avl_struct *root_node;
};
void util_avl_rebalance(struct util_avl_struct *node,
struct util_avl_root *root);
void util_avl_remove(struct util_avl_struct *node, struct util_avl_root *root);
static inline void util_avl_link(struct util_avl_struct *new_node,
struct util_avl_struct *parent,
struct util_avl_struct **nodeplace)
{
new_node->avl_left = AVL_ROOT;
new_node->avl_right = AVL_ROOT;
new_node->parent = parent;
new_node->height = 1;
*nodeplace = new_node;
}
static inline struct util_avl_struct *util_avl_next(
struct util_avl_struct *node)
{
struct util_avl_struct *successor = 0;
if (node)
{
if (node->avl_right)
{
node = node->avl_right;
while (node->avl_left)
node = node->avl_left;
successor = node;
}
else
{
while ((successor = node->parent) && (node == successor->avl_right))
node = successor;
}
}
return successor;
}
static inline struct util_avl_struct *util_avl_prev(
struct util_avl_struct *node)
{
struct util_avl_struct *predecessor = 0;
if (node)
{
if (node->avl_left)
{
node = node->avl_left;
while (node->avl_right)
node = node->avl_right;
predecessor = node;
}
else
{
while ((predecessor = node->parent) &&
(node == predecessor->avl_left))
node = predecessor;
}
}
return predecessor;
}
static inline struct util_avl_struct *util_avl_first(struct util_avl_root *root)
{
struct util_avl_struct *first = root->root_node;
if (first)
{
while (first->avl_left)
first = first->avl_left;
}
return first;
}
static inline struct util_avl_struct *util_avl_last(struct util_avl_root *root)
{
struct util_avl_struct *last = root->root_node;
if (last)
{
while (last->avl_right)
last = last->avl_right;
}
return last;
}
#endif /* __UTIL_TREE_AVL_H__ */
+3 -1
View File
@@ -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 */
/**@}*/
+5
View File
@@ -54,6 +54,11 @@ enum RT_HW_CACHE_OPS
* CPU interfaces
*/
#ifdef RT_USING_CACHE
#ifdef ARCH_RISCV64
#include <cache.h>
#endif
void rt_hw_cpu_icache_enable(void);
void rt_hw_cpu_icache_disable(void);
rt_base_t rt_hw_cpu_icache_status(void);
+1 -26
View File
@@ -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
+1 -1
View File
@@ -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)
{
+13 -2
View File
@@ -11,6 +11,7 @@
#define CPUPORT_H__
#include <armv8.h>
#include <rtdef.h>
#ifdef RT_USING_SMP
typedef union {
@@ -29,12 +30,22 @@ rt_inline void rt_hw_isb(void)
rt_inline void rt_hw_dmb(void)
{
asm volatile ("dmb sy":::"memory");
asm volatile ("dmb ish":::"memory");
}
rt_inline void rt_hw_wmb(void)
{
asm volatile ("dmb ishst":::"memory");
}
rt_inline void rt_hw_rmb(void)
{
asm volatile ("dmb ishld":::"memory");
}
rt_inline void rt_hw_dsb(void)
{
asm volatile ("dsb sy":::"memory");
asm volatile ("dsb ish":::"memory");
}
#endif /*CPUPORT_H__*/
+10 -4
View File
@@ -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();
File diff suppressed because it is too large Load Diff
+52 -81
View File
@@ -11,6 +11,7 @@
#define __MMU_H_
#include <rtthread.h>
#include <mm_aspace.h>
/* normal memory wra mapping type */
#define NORMAL_MEM 0
@@ -25,6 +26,7 @@ struct mem_desc
unsigned long vaddr_end;
unsigned long paddr_start;
unsigned long attr;
struct rt_varea varea;
};
#define MMU_AF_SHIFT 10
@@ -37,60 +39,17 @@ struct mem_desc
#define MMU_AP_KRUN 2UL /* kernel r, user none */
#define MMU_AP_KRUR 3UL /* kernel r, user r */
#define MMU_MAP_K_RO (\
(0x1UL << MMU_AF_SHIFT) |\
(0x2UL << MMU_SHARED_SHIFT) |\
(MMU_AP_KRUN << MMU_AP_SHIFT) |\
(NORMAL_MEM << MMU_MA_SHIFT)\
)
#define MMU_MAP_K_RWCB (\
(0x1UL << MMU_AF_SHIFT) |\
(0x2UL << MMU_SHARED_SHIFT) |\
(MMU_AP_KAUN << MMU_AP_SHIFT) |\
(NORMAL_MEM << MMU_MA_SHIFT)\
)
#define MMU_MAP_K_RW (\
(0x1UL << MMU_AF_SHIFT) |\
(0x2UL << MMU_SHARED_SHIFT) |\
(MMU_AP_KAUN << MMU_AP_SHIFT) |\
(NORMAL_NOCACHE_MEM << MMU_MA_SHIFT)\
)
#define MMU_MAP_K_DEVICE (\
(0x1UL << MMU_AF_SHIFT) |\
(0x2UL << MMU_SHARED_SHIFT) |\
(MMU_AP_KAUN << MMU_AP_SHIFT) |\
(DEVICE_MEM << MMU_MA_SHIFT)\
)
#define MMU_MAP_U_RO (\
(0x1UL << MMU_AF_SHIFT) |\
(0x2UL << MMU_SHARED_SHIFT) |\
(MMU_AP_KRUR << MMU_AP_SHIFT) |\
(NORMAL_NOCACHE_MEM << MMU_MA_SHIFT)\
)
#define MMU_MAP_U_RWCB (\
(0x1UL << MMU_AF_SHIFT) |\
(0x2UL << MMU_SHARED_SHIFT) |\
(MMU_AP_KAUA << MMU_AP_SHIFT) |\
(NORMAL_MEM << MMU_MA_SHIFT)\
)
#define MMU_MAP_U_RW (\
(0x1UL << MMU_AF_SHIFT) |\
(0x2UL << MMU_SHARED_SHIFT) |\
(MMU_AP_KAUA << MMU_AP_SHIFT) |\
(NORMAL_NOCACHE_MEM << MMU_MA_SHIFT)\
)
#define MMU_MAP_U_DEVICE (\
(0x1UL << MMU_AF_SHIFT) |\
(0x2UL << MMU_SHARED_SHIFT) |\
(MMU_AP_KAUA << MMU_AP_SHIFT) |\
(DEVICE_MEM << MMU_MA_SHIFT)\
)
#define MMU_MAP_CUSTOM(ap, mtype) (\
(0x1UL << MMU_AF_SHIFT) |\
(0x2UL << MMU_SHARED_SHIFT) |\
((ap) << MMU_AP_SHIFT) |\
((mtype) << MMU_MA_SHIFT)\
)
#define MMU_MAP_CUSTOM(ap, mtype) \
((0x1UL << MMU_AF_SHIFT) | (0x2UL << MMU_SHARED_SHIFT) | \
((ap) << MMU_AP_SHIFT) | ((mtype) << MMU_MA_SHIFT))
#define MMU_MAP_K_RO MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_MEM)
#define MMU_MAP_K_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_MEM)
#define MMU_MAP_K_RW MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_NOCACHE_MEM)
#define MMU_MAP_K_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUN, DEVICE_MEM)
#define MMU_MAP_U_RO MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_NOCACHE_MEM)
#define MMU_MAP_U_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_MEM)
#define MMU_MAP_U_RW MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_NOCACHE_MEM)
#define MMU_MAP_U_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUA, DEVICE_MEM)
#define ARCH_SECTION_SHIFT 21
#define ARCH_SECTION_SIZE (1 << ARCH_SECTION_SHIFT)
@@ -102,6 +61,7 @@ struct mem_desc
#define ARCH_PAGE_TBL_SIZE (1 << ARCH_PAGE_TBL_SHIFT)
#define ARCH_PAGE_TBL_MASK (ARCH_PAGE_TBL_SIZE - 1)
#define ARCH_VADDR_WIDTH 48
#define ARCH_ADDRESS_WIDTH_BITS 64
#define MMU_MAP_ERROR_VANOTALIGN -1
@@ -109,37 +69,48 @@ struct mem_desc
#define MMU_MAP_ERROR_NOPAGE -3
#define MMU_MAP_ERROR_CONFLICT -4
typedef struct
{
size_t *vtable;
size_t vstart;
size_t vend;
size_t pv_off;
} rt_mmu_info;
#define ARCH_MAP_FAILED ((void *)0x1ffffffffffff)
void rt_hw_mmu_setup_early(unsigned long *tbl0, unsigned long *tbl1, unsigned long size, unsigned long pv_off);
void rt_hw_mmu_setup(struct mem_desc *mdesc, int desc_nr);
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
+80
View File
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-28 WangXiaoyao the first version
*/
#ifndef __TLB_H__
#define __TLB_H__
#include <rtthread.h>
#include <stddef.h>
#include <stdint.h>
#include "mm_aspace.h"
#include "mmu.h"
#define TLBI_ARG(addr, asid) \
({ \
uintptr_t arg = (uintptr_t)(addr) >> 12; \
arg &= (1ull << 44) - 1; \
arg |= (uintptr_t)(asid) << 48; \
(void *)arg; \
})
static inline void rt_hw_tlb_invalidate_all(void)
{
__asm__ volatile(
// ensure updates to pte completed
"dsb ishst\n"
"tlbi vmalle1is\n"
"dsb ish\n"
// after tlb in new context, refresh inst
"isb\n" ::
: "memory");
}
static inline void rt_hw_tlb_invalidate_all_local(void)
{
__asm__ volatile(
// ensure updates to pte completed
"dsb nshst\n"
"tlbi vmalle1is\n"
"dsb nsh\n"
// after tlb in new context, refresh inst
"isb\n" ::
: "memory");
}
static inline void rt_hw_tlb_invalidate_aspace(rt_aspace_t aspace)
{
rt_hw_tlb_invalidate_all_local();
}
static inline void rt_hw_tlb_invalidate_page(rt_aspace_t aspace, void *start)
{
start = TLBI_ARG(start, 0);
__asm__ volatile(
"dsb ishst\n"
"tlbi vaae1is, %0\n"
"dsb ish\n"
"isb\n" ::"r"(start)
: "memory");
}
static inline void rt_hw_tlb_invalidate_range(rt_aspace_t aspace, void *start,
size_t size, size_t stride)
{
if (size < ARCH_PAGE_SIZE)
{
rt_hw_tlb_invalidate_page(aspace, start);
}
else
{
rt_hw_tlb_invalidate_aspace(aspace);
}
}
#endif /* __TLB_H__ */
+45 -4
View File
@@ -14,6 +14,7 @@
#include <armv8.h>
#include "interrupt.h"
#include "mm_fault.h"
#include <backtrace.h>
@@ -48,6 +49,29 @@ void check_user_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *info)
}
}
int _get_type(unsigned long esr)
{
int ret;
int fsc = esr & 0x3f;
switch (fsc)
{
case 0x4:
case 0x5:
case 0x6:
case 0x7:
ret = MM_FAULT_TYPE_PAGE_FAULT;
break;
case 0x9:
case 0xa:
case 0xb:
ret = MM_FAULT_TYPE_ACCESS_FAULT;
break;
default:
ret = MM_FAULT_TYPE_GENERIC;
}
return ret;
}
int check_user_stack(unsigned long esr, struct rt_hw_exp_stack *regs)
{
unsigned char ec;
@@ -55,19 +79,36 @@ int check_user_stack(unsigned long esr, struct rt_hw_exp_stack *regs)
int ret = 0;
ec = (unsigned char)((esr >> 26) & 0x3fU);
enum rt_mm_fault_op fault_op;
enum rt_mm_fault_type fault_type;
switch (ec)
{
case 0x20:
fault_op = MM_FAULT_OP_EXECUTE;
fault_type = _get_type(esr);
break;
case 0x21:
case 0x24:
fault_op = MM_FAULT_OP_WRITE;
fault_type = _get_type(esr);
break;
default:
fault_op = 0;
break;
}
if (fault_op)
{
asm volatile("mrs %0, far_el1":"=r"(dfar));
if (arch_expand_user_stack(dfar))
struct rt_mm_fault_msg msg = {
.fault_op = fault_op,
.fault_type = fault_type,
.vaddr = dfar,
};
if (rt_mm_fault_try_fix(&msg))
{
ret = 1;
}
break;
default:
break;
}
return ret;
}
+10 -9
View File
@@ -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:
+2 -2
View File
@@ -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
+2
View File
@@ -10,6 +10,8 @@
#ifndef CPUPORT_H__
#define CPUPORT_H__
#include <rtthread.h>
/* the exception stack without VFP registers */
struct rt_hw_exp_stack
{
+4 -3
View File
@@ -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
+171 -578
View File
File diff suppressed because it is too large Load Diff
+34 -17
View File
@@ -11,6 +11,7 @@
#define __MMU_H_
#include <rtthread.h>
#include <mm_aspace.h>
#define DESC_SEC (0x2)
#define MEMWBWA ((1<<12)|(3<<2)) /* write back, write allocate */
@@ -87,27 +88,43 @@ struct mem_desc
#define ARCH_TYPE_SUPERSECTION (1 << 18)
#define ARCH_ADDRESS_WIDTH_BITS 32
#define ARCH_VADDR_WIDTH 32
typedef struct
{
size_t *vtable;
size_t vstart;
size_t vend;
size_t pv_off;
} rt_mmu_info;
/**
* *info it's possible to map (-1ul & ~ARCH_PAGE_MASK) but a not aligned -1 is
* never returned on a successful mapping
*/
#define ARCH_MAP_FAILED ((void *)-1)
int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size_t *vtable, size_t pv_off);
int rt_hw_mmu_ioremap_init(rt_mmu_info *mmu_info, void* v_address, size_t size);
int rt_hw_mmu_ioremap_init(struct rt_aspace *aspace, void *v_address, size_t size);
void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_uint32_t size);
#ifdef RT_USING_SMART
void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr);
void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr);
#else
void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr);
#endif
void rt_hw_mmu_setup(struct rt_aspace *aspace, struct mem_desc *mdesc, int desc_nr);
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
+9 -16
View File
@@ -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
+48
View File
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-12-12 WangXiaoyao the first version
*/
#ifndef __TLB_H__
#define __TLB_H__
#include "mm_aspace.h"
#include <rtthread.h>
#include <stddef.h>
#include <stdint.h>
#define dsb(scope) __asm__ volatile("dsb " #scope : : : "memory")
#define isb() __asm__ volatile("isb" : : : "memory")
#define STORE_CP32(r, name...) "mcr " RT_STRINGIFY(CP32(%r, name)) ";"
#define WRITE_CP32(v, name...) do { \
register uint32_t _r = (v); \
asm volatile(STORE_CP32(0, name) : : "r" (_r)); \
} while (0)
static inline void rt_hw_tlb_invalidate_all(void)
{
asm volatile ("mcr p15, 0, r0, c8, c7, 0\ndsb\nisb" ::: "memory");
}
static inline void rt_hw_tlb_invalidate_all_local(void)
{
rt_hw_tlb_invalidate_all();
}
static inline void rt_hw_tlb_invalidate_aspace(rt_aspace_t aspace)
{
rt_hw_tlb_invalidate_all();
}
static inline void rt_hw_tlb_invalidate_range(rt_aspace_t aspace, void *start,
size_t size, size_t stride)
{
rt_hw_tlb_invalidate_all();
}
#endif /* __TLB_H__ */
+19 -9
View File
@@ -8,12 +8,13 @@
* 2013-07-20 Bernard first version
*/
#include <rtthread.h>
#include <rthw.h>
#include <board.h>
#include <backtrace.h>
#include <board.h>
#include <rthw.h>
#include <rtthread.h>
#include "interrupt.h"
#include "mm_fault.h"
#ifdef RT_USING_FINSH
extern long list_thread(void);
@@ -44,14 +45,23 @@ void check_user_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *info)
int check_user_stack(struct rt_hw_exp_stack *regs)
{
void* dfar = RT_NULL;
void *dfar = RT_NULL;
asm volatile("MRC p15, 0, %0, c6, c0, 0" : "=r"(dfar));
asm volatile ("MRC p15, 0, %0, c6, c0, 0":"=r"(dfar));
if (arch_expand_user_stack(dfar))
if ((dfar >= (void *)USER_STACK_VSTART) && (dfar < (void *)USER_STACK_VEND))
{
regs->pc -= 8;
return 1;
struct rt_mm_fault_msg msg = {
.fault_op = MM_FAULT_OP_WRITE,
.fault_type = MM_FAULT_TYPE_PAGE_FAULT,
.vaddr = dfar,
};
if (rt_mm_fault_try_fix(&msg))
{
regs->pc -= 8;
return 1;
}
}
return 0;
}
#endif
@@ -79,7 +89,7 @@ void rt_hw_show_register(struct rt_hw_exp_stack *regs)
rt_kprintf("ttbr0:0x%08x\n", v);
asm volatile ("MRC p15, 0, %0, c6, c0, 0":"=r"(v));
rt_kprintf("dfar:0x%08x\n", v);
rt_kprintf("0x%08x -> 0x%08x\n", v, rt_hw_mmu_v2p(&mmu_info, (void *)v));
rt_kprintf("0x%08x -> 0x%08x\n", v, rt_kmem_v2p((void *)v));
}
#endif
}
+137
View File
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
#ifdef RT_USING_SMART
#include <lwp_arch.h>
#define TRANCE_LEVEL 20
extern rt_ubase_t __text_start[];
extern rt_ubase_t __text_end[];
static char *_get_elf_name(size_t sepc);
void rt_hw_backtrace(rt_uint32_t *ffp, rt_ubase_t sepc)
{
rt_ubase_t *ra;
rt_ubase_t *fp;
rt_ubase_t vas, vae;
int i, j;
rt_kprintf("riscv64-unknown-linux-musl-addr2line -e %s -a -f", _get_elf_name(sepc));
fp = (rt_ubase_t *)ffp;
if (!fp)
{
asm volatile("mv %0, s0"
: "=r"(fp));
}
if (sepc)
{
rt_kprintf(" %p", sepc - 0x4);
}
if (fp > (rt_ubase_t *)USER_VADDR_START && fp < (rt_ubase_t *)USER_VADDR_TOP)
{
vas = USER_VADDR_START;
vae = USER_VADDR_TOP;
}
else
{
vas = (rt_ubase_t)&__text_start;
vae = (rt_ubase_t)&__text_end;
}
for (i = j = 0; i < TRANCE_LEVEL; i++)
{
if (RT_ALIGN((rt_ubase_t)fp, sizeof(void *)) != (rt_ubase_t)fp)
{
break;
}
ra = fp - 1;
if (!_rt_kmem_v2p(ra) || *ra < vas || *ra > vae)
break;
rt_kprintf(" %p", *ra - 0x04);
fp = fp - 2;
if (!_rt_kmem_v2p(fp))
break;
fp = (rt_ubase_t *)(*fp);
if (!fp)
break;
}
rt_kputs("\r\n");
}
static void _assert_backtrace_cb(const char *ex, const char *func, rt_size_t line)
{
rt_hw_interrupt_disable();
rt_kprintf("(%s) assertion failed at function:%s, line number:%d \n", ex, func, line);
rt_hw_backtrace(0, 0);
rt_hw_cpu_shutdown();
}
static int rt_hw_backtrace_init(void)
{
rt_assert_set_hook(_assert_backtrace_cb);
return 0;
}
INIT_BOARD_EXPORT(rt_hw_backtrace_init);
static void backtrace_test(int args, char *argv[])
{
int *p = (void *)-1;
init_fn_t ft = 0;
if (args < 2)
{
rt_kprintf("backtrace_test usage:backtrace_test a(assert)/m(invalid memory)/i(illegal instruction)\r\n");
return;
}
if (!rt_strcmp(argv[1], "a"))
{
rt_kprintf("Assert test:\r\n", argv[1]);
RT_ASSERT(0);
}
else if (!rt_strcmp(argv[1], "m"))
{
rt_kprintf("Access invalid memory:\r\n", argv[1]);
*p = 0;
}
else if (!rt_strcmp(argv[1], "i"))
{
rt_kprintf("Illegal instruction:\r\n", argv[1]);
ft();
}
else
{
rt_kprintf("Unknown cmd :%s.\r\n", argv[1]);
}
}
MSH_CMD_EXPORT(backtrace_test, backtrace test case);
extern struct rt_thread *rt_current_thread;
#define IN_USERSPACE (sepc > USER_VADDR_START && sepc < USER_VADDR_TOP)
static char *_get_elf_name(size_t sepc)
{
return IN_USERSPACE ? rt_current_thread->name : "rtthread.elf";
}
#endif /* RT_USING_SMART */
+2 -2
View File
@@ -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
+3 -4
View File
@@ -14,6 +14,7 @@
#include <rtthread.h>
#include "cpuport.h"
#include "sbi.h"
#include "stack.h"
#include <lwp_arch.h>
@@ -110,10 +111,8 @@ void rt_hw_cpu_shutdown()
rt_kprintf("shutdown...\n");
level = rt_hw_interrupt_disable();
while (level)
{
RT_ASSERT(0);
}
sbi_shutdown();
while (1);
}
int rt_hw_cpu_id(void)
+5 -3
View File
@@ -37,19 +37,21 @@
#define CTX_REG_NR (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR)
#ifndef __ASSEMBLY__
#include <rtthread.h>
rt_inline void rt_hw_dsb()
{
asm volatile("fence":::"memory");
__asm__ volatile("fence":::"memory");
}
rt_inline void rt_hw_dmb()
{
asm volatile("fence":::"memory");
__asm__ volatile("fence":::"memory");
}
rt_inline void rt_hw_isb()
{
asm volatile(OPC_FENCE_I:::"memory");
__asm__ volatile(OPC_FENCE_I:::"memory");
}
int rt_hw_cpu_id(void);
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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:
File diff suppressed because it is too large Load Diff
+67 -29
View File
@@ -13,45 +13,83 @@
#include "riscv.h"
#include "riscv_mmu.h"
#include <mm_aspace.h>
#include <stddef.h>
/* RAM, Flash, or ROM */
#define NORMAL_MEM 0
/* normal nocache memory mapping type */
#define NORMAL_NOCACHE_MEM 1
/* MMIO region */
#define DEVICE_MEM 2
typedef size_t rt_pte_t;
struct mem_desc
{
rt_size_t vaddr_start;
rt_size_t vaddr_end;
rt_size_t paddr_start;
rt_size_t attr;
struct rt_varea varea;
};
#define GET_PF_ID(addr) ((addr) >> PAGE_OFFSET_BIT)
#define GET_PF_OFFSET(addr) __MASKVALUE(addr,PAGE_OFFSET_MASK)
#define GET_L1(addr) __PARTBIT(addr,VPN2_SHIFT,VPN2_BIT)
#define GET_L2(addr) __PARTBIT(addr,VPN1_SHIFT,VPN1_BIT)
#define GET_L3(addr) __PARTBIT(addr,VPN0_SHIFT,VPN0_BIT)
#define GET_PPN(pte) (__PARTBIT(pte,PTE_PPN_SHIFT,PHYSICAL_ADDRESS_WIDTH_BITS - PTE_PPN_SHIFT))
#define GET_PADDR(pte) (GET_PPN(pte) << PAGE_OFFSET_BIT)
#define VPN_TO_PPN(vaddr,pv_off) (((rt_size_t)(vaddr)) + (pv_off))
#define PPN_TO_VPN(paddr,pv_off) (((rt_size_t)(paddr)) - (pv_off))
#define COMBINEVADDR(l1_off,l2_off,l3_off) (((l1_off) << VPN2_SHIFT) | ((l2_off) << VPN1_SHIFT) | ((l3_off) << VPN0_SHIFT))
#define COMBINEPTE(paddr,attr) ((((paddr) >> PAGE_OFFSET_BIT) << PTE_PPN_SHIFT) | (attr))
#define GET_PF_ID(addr) ((addr) >> PAGE_OFFSET_BIT)
#define GET_PF_OFFSET(addr) __MASKVALUE(addr, PAGE_OFFSET_MASK)
#define GET_L1(addr) __PARTBIT(addr, VPN2_SHIFT, VPN2_BIT)
#define GET_L2(addr) __PARTBIT(addr, VPN1_SHIFT, VPN1_BIT)
#define GET_L3(addr) __PARTBIT(addr, VPN0_SHIFT, VPN0_BIT)
#define GET_PPN(pte) \
(__PARTBIT(pte, PTE_PPN_SHIFT, PHYSICAL_ADDRESS_WIDTH_BITS - PTE_PPN_SHIFT))
#define GET_PADDR(pte) (GET_PPN(pte) << PAGE_OFFSET_BIT)
#define VPN_TO_PPN(vaddr, pv_off) (((rt_size_t)(vaddr)) + (pv_off))
#define PPN_TO_VPN(paddr, pv_off) (((rt_size_t)(paddr)) - (pv_off))
#define COMBINEVADDR(l1_off, l2_off, l3_off) \
(((l1_off) << VPN2_SHIFT) | ((l2_off) << VPN1_SHIFT) | \
((l3_off) << VPN0_SHIFT))
#define COMBINEPTE(paddr, attr) \
((((paddr) >> PAGE_OFFSET_BIT) << PTE_PPN_SHIFT) | (attr))
typedef struct
{
size_t *vtable;
size_t vstart;
size_t vend;
size_t pv_off;
}rt_mmu_info;
#define ARCH_ADDRESS_WIDTH_BITS 64
#define MMU_MAP_ERROR_VANOTALIGN -1
#define MMU_MAP_ERROR_PANOTALIGN -2
#define MMU_MAP_ERROR_NOPAGE -3
#define MMU_MAP_ERROR_CONFLICT -4
void *rt_hw_mmu_tbl_get();
void rt_hw_mmu_switch(void *mmu_table);
int rt_hw_mmu_map_init(rt_mmu_info *mmu_info,void *v_address,rt_size_t size,rt_size_t *vtable,rt_size_t pv_off);
void rt_hw_mmu_kernel_map_init(rt_mmu_info *mmu_info,rt_size_t vaddr_start,rt_size_t size);
void *_rt_hw_mmu_map(rt_mmu_info *mmu_info,void *v_addr,void *p_addr,rt_size_t size,rt_size_t attr);
void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size,rt_size_t attr);
void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size);
void *rt_hw_mmu_map(rt_mmu_info *mmu_info,void *v_addr,void *p_addr,rt_size_t size,rt_size_t attr);
void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size,rt_size_t attr);
void rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size);
void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info,void *v_addr);
void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info,void *v_addr);
int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, rt_size_t size,
rt_size_t *vtable, rt_size_t pv_off);
void rt_hw_mmu_setup(rt_aspace_t aspace, struct mem_desc *mdesc, int desc_nr);
void rt_hw_mmu_kernel_map_init(rt_aspace_t aspace, rt_size_t vaddr_start,
rt_size_t size);
void *rt_hw_mmu_map(rt_aspace_t aspace, void *v_addr, void *p_addr, size_t size,
size_t attr);
void rt_hw_mmu_unmap(rt_aspace_t aspace, void *v_addr, size_t size);
void rt_hw_aspace_switch(rt_aspace_t aspace);
void *rt_hw_mmu_v2p(rt_aspace_t aspace, void *vaddr);
static inline void *_rt_kmem_v2p(void *vaddr)
{
return rt_hw_mmu_v2p(&rt_kernel_space, vaddr);
}
static inline void *rt_kmem_v2p(void *vaddr)
{
MM_PGTBL_LOCK(&rt_kernel_space);
void *paddr = _rt_kmem_v2p(vaddr);
MM_PGTBL_UNLOCK(&rt_kernel_space);
return paddr;
}
enum rt_mmu_cntl
{
MMU_CNTL_NONCACHE,
MMU_CNTL_CACHE,
MMU_CNTL_DUMMY_END,
};
int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size,
enum rt_mmu_cntl cmd);
#endif

Some files were not shown because too many files have changed in this diff Show More