Explorar el Código

!583 添加对arm v7指令集的ASID支持
Merge pull request !583 from chy/rt-smart-asid

bernard hace 3 años
padre
commit
dd20354947

+ 5 - 0
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"

+ 47 - 0
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

+ 2 - 0
components/lwp/arch/arm/cortex-a/lwp_arch.h

@@ -38,6 +38,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

+ 5 - 0
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);

+ 6 - 0
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;

+ 8 - 0
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
     }
 }
 

+ 10 - 9
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)

+ 11 - 3
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 */