diff --git a/components/lwp/Kconfig b/components/lwp/Kconfig index da62bb0c640854a6a4c087341942d9a53861601b..c4178c82747a20e57c5a865a2fb501e8481a1381 100644 --- a/components/lwp/Kconfig +++ b/components/lwp/Kconfig @@ -34,6 +34,11 @@ if RT_USING_LWP int "The maximum number of lwp thread id" default 64 + config LWP_ENABLE_ASID + bool "The switch of ASID feature" + depends on ARCH_ARM_CORTEX_A + default y + if ARCH_MM_MMU config RT_LWP_SHM_MAX_NR int "The maximum number of shared memory" diff --git a/components/lwp/arch/arm/cortex-a/lwp_arch.c b/components/lwp/arch/arm/cortex-a/lwp_arch.c index 0d0d0cf39f1936bc3bf67e34d02a6804e349e331..9bf18f61d69b0befff87e7e7004ffd9a3831e5ef 100644 --- a/components/lwp/arch/arm/cortex-a/lwp_arch.c +++ b/components/lwp/arch/arm/cortex-a/lwp_arch.c @@ -87,4 +87,51 @@ int arch_expand_user_stack(void *addr) return ret; } + +#define MAX_ASID_BITS 8 +#define MAX_ASID (1 << MAX_ASID_BITS) +static uint64_t global_generation = 1; +static char asid_valid_bitmap[MAX_ASID]; +unsigned int arch_get_asid(struct rt_lwp *lwp) +{ + if (lwp == RT_NULL) + { + // kernel + return 0; + } + + if (lwp->generation == global_generation) + { + return lwp->asid; + } + + if (lwp->asid && !asid_valid_bitmap[lwp->asid]) + { + asid_valid_bitmap[lwp->asid] = 1; + return lwp->asid; + } + + for (unsigned i = 1; i < MAX_ASID; i++) + { + if (asid_valid_bitmap[i] == 0) + { + asid_valid_bitmap[i] = 1; + lwp->generation = global_generation; + lwp->asid = i; + return lwp->asid; + } + } + + global_generation++; + memset(asid_valid_bitmap, 0, MAX_ASID * sizeof(char)); + + asid_valid_bitmap[1] = 1; + lwp->generation = global_generation; + lwp->asid = 1; + + asm volatile ("mcr p15, 0, r0, c8, c7, 0\ndsb\nisb" ::: "memory"); + + return lwp->asid; +} + #endif diff --git a/components/lwp/arch/arm/cortex-a/lwp_arch.h b/components/lwp/arch/arm/cortex-a/lwp_arch.h index 69fa42fc2aa7d5caa523e958a21e5f314ad63162..18e4e0b3696464a8baa359c3974a2cd1a656eaff 100644 --- a/components/lwp/arch/arm/cortex-a/lwp_arch.h +++ b/components/lwp/arch/arm/cortex-a/lwp_arch.h @@ -43,6 +43,8 @@ rt_inline void icache_invalid_all(void) asm volatile ("mcr p15, 0, r0, c7, c5, 0\ndsb\nisb":::"memory");//iciallu } +unsigned int arch_get_asid(struct rt_lwp *lwp); + #ifdef __cplusplus } #endif diff --git a/components/lwp/lwp.h b/components/lwp/lwp.h index 319802570d9cacd8123a9d10d5ab9c72f0e99b9c..2725f0b83849446d14e261530d830124bf6feb99 100644 --- a/components/lwp/lwp.h +++ b/components/lwp/lwp.h @@ -120,6 +120,11 @@ struct rt_lwp char working_directory[DFS_PATH_MAX]; int debug; uint32_t bak_first_ins; + +#ifdef LWP_ENABLE_ASID + uint64_t generation; + unsigned int asid; +#endif }; struct rt_lwp *lwp_self(void); diff --git a/components/lwp/lwp_pid.c b/components/lwp/lwp_pid.c index b6e3b67ae395a73098bc7dea122992ea70cc430e..809339f68f6115f5573d3219c36f23c5d30b7104 100644 --- a/components/lwp/lwp_pid.c +++ b/components/lwp/lwp_pid.c @@ -336,6 +336,12 @@ struct rt_lwp* lwp_new(void) } lwp->pid = pid; lwp_pid_set_lwp(pid, lwp); + +#ifdef LWP_ENABLE_ASID + lwp->generation = 0; + lwp->asid = 0; +#endif + out: rt_hw_interrupt_enable(level); return lwp; diff --git a/components/lwp/lwp_user_mm.c b/components/lwp/lwp_user_mm.c index f812ebcedc368ee8d92344a1c79817b98f4d8eb2..73097d814b8ac525161502d7659b78217d88e523 100644 --- a/components/lwp/lwp_user_mm.c +++ b/components/lwp/lwp_user_mm.c @@ -29,7 +29,11 @@ int lwp_user_space_init(struct rt_lwp *lwp) return arch_user_space_init(lwp); } +#ifdef LWP_ENABLE_ASID +void rt_hw_mmu_switch(void *mtable, unsigned int pid, unsigned int asid); +#else void rt_hw_mmu_switch(void *mtable); +#endif void *rt_hw_mmu_tbl_get(void); void lwp_mmu_switch(struct rt_thread *thread) { @@ -49,7 +53,11 @@ void lwp_mmu_switch(struct rt_thread *thread) pre_mmu_table = rt_hw_mmu_tbl_get(); if (pre_mmu_table != new_mmu_table) { +#ifdef LWP_ENABLE_ASID + rt_hw_mmu_switch(new_mmu_table, l ? l->pid : 0, arch_get_asid(l)); +#else rt_hw_mmu_switch(new_mmu_table); +#endif } } diff --git a/libcpu/arm/cortex-a/mmu.h b/libcpu/arm/cortex-a/mmu.h index a018d292c6343197516927950f0343984b3b31bc..3ffcc61d71c7710d201d25632c9df34935867c45 100644 --- a/libcpu/arm/cortex-a/mmu.h +++ b/libcpu/arm/cortex-a/mmu.h @@ -61,15 +61,16 @@ struct mem_desc #define MMU_MAP_MTBL_TEX(x) (x<<6) #define MMU_MAP_MTBL_AP2(x) (x<<9) #define MMU_MAP_MTBL_SHARE (1<<10) - -#define MMU_MAP_K_RO (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(1)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) -#define MMU_MAP_K_RWCB (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) -#define MMU_MAP_K_RW (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_SHARE) -#define MMU_MAP_K_DEVICE (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_SHARE) -#define MMU_MAP_U_RO (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(2)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) -#define MMU_MAP_U_RWCB (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) -#define MMU_MAP_U_RW (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_SHARE) -#define MMU_MAP_U_DEVICE (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_MTBL_NG(x) (x<<11) + +#define MMU_MAP_K_RO (MMU_MAP_MTBL_NG(0))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(1)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_K_RWCB (MMU_MAP_MTBL_NG(0))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_K_RW (MMU_MAP_MTBL_NG(0))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_K_DEVICE (MMU_MAP_MTBL_NG(0))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_U_RO (MMU_MAP_MTBL_NG(1))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(2)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_U_RWCB (MMU_MAP_MTBL_NG(1))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_U_RW (MMU_MAP_MTBL_NG(1))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_U_DEVICE (MMU_MAP_MTBL_NG(1))|(MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_SHARE) #define ARCH_SECTION_SHIFT 20 #define ARCH_SECTION_SIZE (1 << ARCH_SECTION_SHIFT) diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S index 35494ce04ad80237b43e6965137e4da50697917b..9e652f0240434ba00e75154ad8f50ea70087efa6 100644 --- a/libcpu/arm/cortex-a/start_gcc.S +++ b/libcpu/arm/cortex-a/start_gcc.S @@ -269,12 +269,20 @@ rt_hw_set_process_id: .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 */ - /* invalid tlb */ - mov r0, #0 - mcr p15, 0, r0, c8, c7, 0 + 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 */