summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchenhy0106 <[email protected]>2023-01-29 02:08:40 +0800
committerGitHub <[email protected]>2023-01-28 13:08:40 -0500
commit9db73a47c45f94668bb7a5947402ec5982beedd1 (patch)
tree642242c39fbd35edc52259fc48728d6c053dfc92
parentaf143ee3f9e84927148f3d24ebb6c032142a3bda (diff)
为c906添加asid支持 (#6870)
* [rt-smart] asid for c906
-rw-r--r--components/mm/mm_aspace.h2
-rw-r--r--libcpu/risc-v/t-head/c906/mmu.c60
-rw-r--r--libcpu/risc-v/t-head/c906/riscv_mmu.h6
3 files changed, 65 insertions, 3 deletions
diff --git a/components/mm/mm_aspace.h b/components/mm/mm_aspace.h
index 900b3635be..a8cf6e8339 100644
--- a/components/mm/mm_aspace.h
+++ b/components/mm/mm_aspace.h
@@ -53,6 +53,8 @@ typedef struct rt_aspace
struct _aspace_tree tree;
struct rt_mutex bst_lock;
+
+ rt_uint64_t asid;
} *rt_aspace_t;
typedef struct rt_varea
diff --git a/libcpu/risc-v/t-head/c906/mmu.c b/libcpu/risc-v/t-head/c906/mmu.c
index bdcfa7587d..dc3ba0cfdd 100644
--- a/libcpu/risc-v/t-head/c906/mmu.c
+++ b/libcpu/risc-v/t-head/c906/mmu.c
@@ -41,14 +41,70 @@ static void *current_mmu_table = RT_NULL;
volatile __attribute__((aligned(4 * 1024)))
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)
{
uintptr_t page_table = (uintptr_t)_rt_kmem_v2p(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) |
+ (asid << PPN_BITS) |
((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()
@@ -482,6 +538,8 @@ void rt_hw_mmu_setup(rt_aspace_t aspace, struct mem_desc *mdesc, int desc_nr)
mdesc++;
}
+ _asid_init();
+
rt_hw_aspace_switch(&rt_kernel_space);
rt_page_cleanup();
}
diff --git a/libcpu/risc-v/t-head/c906/riscv_mmu.h b/libcpu/risc-v/t-head/c906/riscv_mmu.h
index 84b9097eaf..ddb3d0277d 100644
--- a/libcpu/risc-v/t-head/c906/riscv_mmu.h
+++ b/libcpu/risc-v/t-head/c906/riscv_mmu.h
@@ -63,8 +63,8 @@
#define PAGE_ATTR_CB (PTE_BUF | PTE_CACHE)
#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)
@@ -81,6 +81,8 @@
#define SATP_MODE_SV57 10
#define SATP_MODE_SV64 11
+#define PPN_BITS 44
+
#define ARCH_VADDR_WIDTH 39
#define SATP_MODE SATP_MODE_SV39