浏览代码

为c906添加asid支持 (#6870)

* [rt-smart] asid for c906
chenhy0106 2 年之前
父节点
当前提交
9db73a47c4
共有 3 个文件被更改,包括 65 次插入3 次删除
  1. 2 0
      components/mm/mm_aspace.h
  2. 59 1
      libcpu/risc-v/t-head/c906/mmu.c
  3. 4 2
      libcpu/risc-v/t-head/c906/riscv_mmu.h

+ 2 - 0
components/mm/mm_aspace.h

@@ -53,6 +53,8 @@ typedef struct rt_aspace
 
 
     struct _aspace_tree tree;
     struct _aspace_tree tree;
     struct rt_mutex bst_lock;
     struct rt_mutex bst_lock;
+
+    rt_uint64_t asid;
 } *rt_aspace_t;
 } *rt_aspace_t;
 
 
 typedef struct rt_varea
 typedef struct rt_varea

+ 59 - 1
libcpu/risc-v/t-head/c906/mmu.c

@@ -41,14 +41,70 @@ static void *current_mmu_table = RT_NULL;
 volatile __attribute__((aligned(4 * 1024)))
 volatile __attribute__((aligned(4 * 1024)))
 rt_ubase_t MMUTable[__SIZE(VPN2_BIT)];
 rt_ubase_t MMUTable[__SIZE(VPN2_BIT)];
 
 
+static rt_uint8_t ASID_BITS = 0;
+static rt_uint16_t next_asid;
+static rt_uint64_t global_asid_generation;
+#define ASID_MASK ((1 << ASID_BITS) - 1)
+#define ASID_FIRST_GENERATION (1 << ASID_BITS)
+#define MAX_ASID ASID_FIRST_GENERATION
+
+static void _asid_init()
+{
+    unsigned int satp_reg = read_csr(satp);
+    satp_reg |= (((rt_uint64_t)0xffff) << PPN_BITS);
+    write_csr(satp, satp_reg);
+    unsigned short valid_asid_bit = ((read_csr(satp) >> PPN_BITS) & 0xffff);
+
+    // The maximal value of ASIDLEN, is 9 for Sv32 or 16 for Sv39, Sv48, and Sv57
+    for (unsigned i = 0; i < 16; i++)
+    {
+        if (!(valid_asid_bit & 0x1))
+        {
+            break;
+        }
+
+        valid_asid_bit >>= 1;
+        ASID_BITS++;
+    }
+
+    global_asid_generation = ASID_FIRST_GENERATION;
+    next_asid = 1;
+}
+
+static rt_uint64_t _asid_check_switch(rt_aspace_t aspace)
+{
+    if ((aspace->asid ^ global_asid_generation) >> ASID_BITS) // not same generation
+    {
+        if (next_asid != MAX_ASID)
+        {
+            aspace->asid = global_asid_generation | next_asid;
+            next_asid++;
+        }
+        else
+        {
+            // scroll to next generation
+            global_asid_generation += ASID_FIRST_GENERATION;
+            next_asid = 1;
+            rt_hw_tlb_invalidate_all_local();
+
+            aspace->asid = global_asid_generation | next_asid;
+            next_asid++;
+        }
+    }
+
+    return aspace->asid & ASID_MASK;
+}
+
 void rt_hw_aspace_switch(rt_aspace_t aspace)
 void rt_hw_aspace_switch(rt_aspace_t aspace)
 {
 {
     uintptr_t page_table = (uintptr_t)_rt_kmem_v2p(aspace->page_table);
     uintptr_t page_table = (uintptr_t)_rt_kmem_v2p(aspace->page_table);
     current_mmu_table = aspace->page_table;
     current_mmu_table = aspace->page_table;
 
 
+    rt_uint64_t asid = _asid_check_switch(aspace);
     write_csr(satp, (((size_t)SATP_MODE) << SATP_MODE_OFFSET) |
     write_csr(satp, (((size_t)SATP_MODE) << SATP_MODE_OFFSET) |
+                        (asid << PPN_BITS) |
                         ((rt_ubase_t)page_table >> PAGE_OFFSET_BIT));
                         ((rt_ubase_t)page_table >> PAGE_OFFSET_BIT));
-    rt_hw_tlb_invalidate_all_local();
+    asm volatile("sfence.vma x0,%0"::"r"(asid):"memory");
 }
 }
 
 
 void *rt_hw_mmu_tbl_get()
 void *rt_hw_mmu_tbl_get()
@@ -482,6 +538,8 @@ void rt_hw_mmu_setup(rt_aspace_t aspace, struct mem_desc *mdesc, int desc_nr)
         mdesc++;
         mdesc++;
     }
     }
 
 
+    _asid_init();
+
     rt_hw_aspace_switch(&rt_kernel_space);
     rt_hw_aspace_switch(&rt_kernel_space);
     rt_page_cleanup();
     rt_page_cleanup();
 }
 }

+ 4 - 2
libcpu/risc-v/t-head/c906/riscv_mmu.h

@@ -63,8 +63,8 @@
 #define PAGE_ATTR_CB    (PTE_BUF | PTE_CACHE)
 #define PAGE_ATTR_CB    (PTE_BUF | PTE_CACHE)
 #define PAGE_ATTR_DEV   (PTE_SO)
 #define PAGE_ATTR_DEV   (PTE_SO)
 
 
-#define PAGE_DEFAULT_ATTR_LEAF (PTE_SHARE | PTE_BUF | PTE_CACHE | PTE_A | PTE_D | PTE_G | PTE_U | PAGE_ATTR_RWX | PTE_V)
-#define PAGE_DEFAULT_ATTR_NEXT (PTE_SHARE | PTE_BUF | PTE_CACHE | PTE_A | PTE_D | PTE_G | PTE_V)
+#define PAGE_DEFAULT_ATTR_LEAF (PTE_SHARE | PTE_BUF | PTE_CACHE | PTE_A | PTE_D | PTE_U | PAGE_ATTR_RWX | PTE_V)
+#define PAGE_DEFAULT_ATTR_NEXT (PTE_SHARE | PTE_BUF | PTE_CACHE | PTE_A | PTE_D | PTE_V)
 
 
 #define PAGE_IS_LEAF(pte) __MASKVALUE(pte, PAGE_ATTR_RWX)
 #define PAGE_IS_LEAF(pte) __MASKVALUE(pte, PAGE_ATTR_RWX)
 
 
@@ -81,6 +81,8 @@
 #define SATP_MODE_SV57      10
 #define SATP_MODE_SV57      10
 #define SATP_MODE_SV64      11
 #define SATP_MODE_SV64      11
 
 
+#define PPN_BITS            44
+
 #define ARCH_VADDR_WIDTH        39
 #define ARCH_VADDR_WIDTH        39
 #define SATP_MODE               SATP_MODE_SV39
 #define SATP_MODE               SATP_MODE_SV39