mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2026-09-08 18:21:29 +01:00
lib: sbi: Allow platforms to override local TLB operations
Some T-Head based processors, for example the Sophgo SG2044, have a JTLB errata that requires special handling of certain TLB maintenance instructions (sfence.vma). Introduce a sbi_tlb_local_operations structure so platforms can provide custom local TLB flush implementations. Use it to implement the JTLB workaround on affected SoCs (currently Sophgo SG2044). Signed-off-by: Xiang W <wangxiang@iscas.ac.cn> Signed-off-by: Han Gao <gaohan@iscas.ac.cn> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20260617112925.1144190-2-wangxiang@iscas.ac.cn Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
+39
-7
@@ -29,6 +29,38 @@ static unsigned long tlb_fifo_off;
|
||||
static unsigned long tlb_fifo_mem_off;
|
||||
static unsigned long tlb_range_flush_limit;
|
||||
|
||||
static void sbi_tlb_local_fence_i(struct sbi_tlb_info *tinfo);
|
||||
static void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo);
|
||||
static void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo);
|
||||
static void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo);
|
||||
static void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo);
|
||||
static void sbi_tlb_local_hfence_vvma_asid(struct sbi_tlb_info *tinfo);
|
||||
static void sbi_tlb_local_hfence_vvma(struct sbi_tlb_info *tinfo);
|
||||
|
||||
static struct sbi_tlb_local_operations default_tlb_local_ops = {
|
||||
.local_fence_i = sbi_tlb_local_fence_i,
|
||||
.local_sfence_vma = sbi_tlb_local_sfence_vma,
|
||||
.local_sfence_vma_asid = sbi_tlb_local_sfence_vma_asid,
|
||||
.local_hfence_gvma_vmid = sbi_tlb_local_hfence_gvma_vmid,
|
||||
.local_hfence_gvma = sbi_tlb_local_hfence_gvma,
|
||||
.local_hfence_vvma_asid = sbi_tlb_local_hfence_vvma_asid,
|
||||
.local_hfence_vvma = sbi_tlb_local_hfence_vvma
|
||||
};
|
||||
|
||||
static const struct sbi_tlb_local_operations *tlb_local_ops =
|
||||
&default_tlb_local_ops;
|
||||
|
||||
const struct sbi_tlb_local_operations *sbi_tlb_get_local_operations(void)
|
||||
{
|
||||
return tlb_local_ops;
|
||||
}
|
||||
|
||||
void sbi_tlb_set_local_operations(
|
||||
const struct sbi_tlb_local_operations *ops)
|
||||
{
|
||||
tlb_local_ops = ops;
|
||||
}
|
||||
|
||||
void __sbi_sfence_vma_all(void)
|
||||
{
|
||||
__asm__ __volatile("sfence.vma");
|
||||
@@ -183,25 +215,25 @@ static void tlb_entry_local_process(struct sbi_tlb_info *data)
|
||||
|
||||
switch (data->type) {
|
||||
case SBI_TLB_FENCE_I:
|
||||
sbi_tlb_local_fence_i(data);
|
||||
tlb_local_ops->local_fence_i(data);
|
||||
break;
|
||||
case SBI_TLB_SFENCE_VMA:
|
||||
sbi_tlb_local_sfence_vma(data);
|
||||
tlb_local_ops->local_sfence_vma(data);
|
||||
break;
|
||||
case SBI_TLB_SFENCE_VMA_ASID:
|
||||
sbi_tlb_local_sfence_vma_asid(data);
|
||||
tlb_local_ops->local_sfence_vma_asid(data);
|
||||
break;
|
||||
case SBI_TLB_HFENCE_GVMA_VMID:
|
||||
sbi_tlb_local_hfence_gvma_vmid(data);
|
||||
tlb_local_ops->local_hfence_gvma_vmid(data);
|
||||
break;
|
||||
case SBI_TLB_HFENCE_GVMA:
|
||||
sbi_tlb_local_hfence_gvma(data);
|
||||
tlb_local_ops->local_hfence_gvma(data);
|
||||
break;
|
||||
case SBI_TLB_HFENCE_VVMA_ASID:
|
||||
sbi_tlb_local_hfence_vvma_asid(data);
|
||||
tlb_local_ops->local_hfence_vvma_asid(data);
|
||||
break;
|
||||
case SBI_TLB_HFENCE_VVMA:
|
||||
sbi_tlb_local_hfence_vvma(data);
|
||||
tlb_local_ops->local_hfence_vvma(data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user