|
@@ -32,7 +32,7 @@ static void sbi_tlb_flush_all(void)
|
|
|
__asm__ __volatile("sfence.vma");
|
|
|
}
|
|
|
|
|
|
-static void sbi_tlb_hfence_vvma(struct sbi_tlb_info *tinfo)
|
|
|
+void sbi_tlb_local_hfence_vvma(struct sbi_tlb_info *tinfo)
|
|
|
{
|
|
|
unsigned long start = tinfo->start;
|
|
|
unsigned long size = tinfo->size;
|
|
@@ -55,7 +55,7 @@ done:
|
|
|
csr_write(CSR_HGATP, hgatp);
|
|
|
}
|
|
|
|
|
|
-static void sbi_tlb_hfence_gvma(struct sbi_tlb_info *tinfo)
|
|
|
+void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo)
|
|
|
{
|
|
|
unsigned long start = tinfo->start;
|
|
|
unsigned long size = tinfo->size;
|
|
@@ -71,7 +71,7 @@ static void sbi_tlb_hfence_gvma(struct sbi_tlb_info *tinfo)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void sbi_tlb_sfence_vma(struct sbi_tlb_info *tinfo)
|
|
|
+void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo)
|
|
|
{
|
|
|
unsigned long start = tinfo->start;
|
|
|
unsigned long size = tinfo->size;
|
|
@@ -90,7 +90,7 @@ static void sbi_tlb_sfence_vma(struct sbi_tlb_info *tinfo)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void sbi_tlb_hfence_vvma_asid(struct sbi_tlb_info *tinfo)
|
|
|
+void sbi_tlb_local_hfence_vvma_asid(struct sbi_tlb_info *tinfo)
|
|
|
{
|
|
|
unsigned long start = tinfo->start;
|
|
|
unsigned long size = tinfo->size;
|
|
@@ -119,7 +119,7 @@ done:
|
|
|
csr_write(CSR_HGATP, hgatp);
|
|
|
}
|
|
|
|
|
|
-static void sbi_tlb_hfence_gvma_vmid(struct sbi_tlb_info *tinfo)
|
|
|
+void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo)
|
|
|
{
|
|
|
unsigned long start = tinfo->start;
|
|
|
unsigned long size = tinfo->size;
|
|
@@ -141,7 +141,7 @@ static void sbi_tlb_hfence_gvma_vmid(struct sbi_tlb_info *tinfo)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void sbi_tlb_sfence_vma_asid(struct sbi_tlb_info *tinfo)
|
|
|
+void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo)
|
|
|
{
|
|
|
unsigned long start = tinfo->start;
|
|
|
unsigned long size = tinfo->size;
|
|
@@ -170,35 +170,9 @@ static void sbi_tlb_sfence_vma_asid(struct sbi_tlb_info *tinfo)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void sbi_tlb_local_flush(struct sbi_tlb_info *tinfo)
|
|
|
+void sbi_tlb_local_fence_i(struct sbi_tlb_info *tinfo)
|
|
|
{
|
|
|
- switch (tinfo->type) {
|
|
|
- case SBI_TLB_FLUSH_VMA:
|
|
|
- sbi_tlb_sfence_vma(tinfo);
|
|
|
- break;
|
|
|
- case SBI_TLB_FLUSH_VMA_ASID:
|
|
|
- sbi_tlb_sfence_vma_asid(tinfo);
|
|
|
- break;
|
|
|
- case SBI_TLB_FLUSH_GVMA:
|
|
|
- sbi_tlb_hfence_gvma(tinfo);
|
|
|
- break;
|
|
|
- case SBI_TLB_FLUSH_GVMA_VMID:
|
|
|
- sbi_tlb_hfence_gvma_vmid(tinfo);
|
|
|
- break;
|
|
|
- case SBI_TLB_FLUSH_VVMA:
|
|
|
- sbi_tlb_hfence_vvma(tinfo);
|
|
|
- break;
|
|
|
- case SBI_TLB_FLUSH_VVMA_ASID:
|
|
|
- sbi_tlb_hfence_vvma_asid(tinfo);
|
|
|
- break;
|
|
|
- case SBI_ITLB_FLUSH:
|
|
|
- __asm__ __volatile("fence.i");
|
|
|
- break;
|
|
|
- default:
|
|
|
- sbi_printf("Invalid tlb flush request type [%lu]\n",
|
|
|
- tinfo->type);
|
|
|
- }
|
|
|
- return;
|
|
|
+ __asm__ __volatile("fence.i");
|
|
|
}
|
|
|
|
|
|
static void sbi_tlb_entry_process(struct sbi_tlb_info *tinfo)
|
|
@@ -207,7 +181,7 @@ static void sbi_tlb_entry_process(struct sbi_tlb_info *tinfo)
|
|
|
struct sbi_scratch *rscratch = NULL;
|
|
|
unsigned long *rtlb_sync = NULL;
|
|
|
|
|
|
- sbi_tlb_local_flush(tinfo);
|
|
|
+ tinfo->local_fn(tinfo);
|
|
|
|
|
|
sbi_hartmask_for_each_hart(rhartid, &tinfo->smask) {
|
|
|
rscratch = sbi_hartid_to_scratch(rhartid);
|
|
@@ -316,13 +290,13 @@ static int sbi_tlb_update_cb(void *in, void *data)
|
|
|
curr = (struct sbi_tlb_info *)data;
|
|
|
next = (struct sbi_tlb_info *)in;
|
|
|
|
|
|
- if (next->type == SBI_TLB_FLUSH_VMA_ASID &&
|
|
|
- curr->type == SBI_TLB_FLUSH_VMA_ASID) {
|
|
|
+ if (next->local_fn == sbi_tlb_local_sfence_vma_asid &&
|
|
|
+ curr->local_fn == sbi_tlb_local_sfence_vma_asid) {
|
|
|
if (next->asid == curr->asid)
|
|
|
ret = __sbi_tlb_range_check(curr, next);
|
|
|
- } else if (next->type == SBI_TLB_FLUSH_VMA &&
|
|
|
- curr->type == SBI_TLB_FLUSH_VMA) {
|
|
|
- ret = __sbi_tlb_range_check(curr, next);
|
|
|
+ } else if (next->local_fn == sbi_tlb_local_sfence_vma &&
|
|
|
+ curr->local_fn == sbi_tlb_local_sfence_vma) {
|
|
|
+ ret = __sbi_tlb_range_check(curr, next);
|
|
|
}
|
|
|
|
|
|
return ret;
|
|
@@ -352,7 +326,7 @@ static int sbi_tlb_update(struct sbi_scratch *scratch,
|
|
|
* then just do a local flush and return;
|
|
|
*/
|
|
|
if (remote_hartid == curr_hartid) {
|
|
|
- sbi_tlb_local_flush(tinfo);
|
|
|
+ tinfo->local_fn(tinfo);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
@@ -391,6 +365,9 @@ static u32 tlb_event = SBI_IPI_EVENT_MAX;
|
|
|
|
|
|
int sbi_tlb_request(ulong hmask, ulong hbase, struct sbi_tlb_info *tinfo)
|
|
|
{
|
|
|
+ if (!tinfo->local_fn)
|
|
|
+ return SBI_EINVAL;
|
|
|
+
|
|
|
return sbi_ipi_send_many(hmask, hbase, tlb_event, tinfo);
|
|
|
}
|
|
|
|