forked from Mirrors/opensbi
lib: sbi: Allow custom local TLB flush function
Currently, we have fixed TLB flush types supported by the remote TLB library. This approach is not flexible and does not allow custom local TLB flush function. For example, after updating PMP entries on a set of HARTs at runtime, we have to flush TLB on these HARTs as well. To support custom local TLB flush function, we replace the "type" field of "struct sbi_tlb_info" with a local TLB flush function pointer. We also provide definitions of standard TLB flush operations (such as fence_i, sfence.vma, hfence.vvma, hfence.gvma, etc). Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
This commit is contained in:
@@ -62,41 +62,43 @@ static int sbi_ecall_rfence_handler(unsigned long extid, unsigned long funcid,
|
||||
switch (funcid) {
|
||||
case SBI_EXT_RFENCE_REMOTE_FENCE_I:
|
||||
SBI_TLB_INFO_INIT(&tlb_info, 0, 0, 0, 0,
|
||||
SBI_ITLB_FLUSH, source_hart);
|
||||
sbi_tlb_local_fence_i, source_hart);
|
||||
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
|
||||
break;
|
||||
case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA:
|
||||
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, 0,
|
||||
SBI_TLB_FLUSH_GVMA, source_hart);
|
||||
sbi_tlb_local_hfence_gvma, source_hart);
|
||||
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
|
||||
break;
|
||||
case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID:
|
||||
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, regs->a4,
|
||||
SBI_TLB_FLUSH_GVMA_VMID, source_hart);
|
||||
sbi_tlb_local_hfence_gvma_vmid,
|
||||
source_hart);
|
||||
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
|
||||
break;
|
||||
case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA:
|
||||
vmid = (csr_read(CSR_HGATP) & HGATP_VMID_MASK);
|
||||
vmid = vmid >> HGATP_VMID_SHIFT;
|
||||
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, vmid,
|
||||
SBI_TLB_FLUSH_VVMA, source_hart);
|
||||
sbi_tlb_local_hfence_vvma, source_hart);
|
||||
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
|
||||
break;
|
||||
case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID:
|
||||
vmid = (csr_read(CSR_HGATP) & HGATP_VMID_MASK);
|
||||
vmid = vmid >> HGATP_VMID_SHIFT;
|
||||
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, regs->a4,
|
||||
vmid, SBI_TLB_FLUSH_VVMA_ASID, source_hart);
|
||||
vmid, sbi_tlb_local_hfence_vvma_asid,
|
||||
source_hart);
|
||||
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
|
||||
break;
|
||||
case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA:
|
||||
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, 0,
|
||||
SBI_TLB_FLUSH_VMA, source_hart);
|
||||
sbi_tlb_local_sfence_vma, source_hart);
|
||||
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
|
||||
break;
|
||||
case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID:
|
||||
SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, regs->a4, 0,
|
||||
SBI_TLB_FLUSH_VMA_ASID, source_hart);
|
||||
sbi_tlb_local_sfence_vma_asid, source_hart);
|
||||
ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
|
||||
break;
|
||||
default:
|
||||
|
Reference in New Issue
Block a user