1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- /*
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2020 Western Digital Corporation or its affiliates.
- *
- * Authors:
- * Anup Patel <anup.patel@wdc.com>
- * Atish Patra <atish.patra@wdc.com>
- */
- #include <sbi/riscv_asm.h>
- #include <sbi/sbi_error.h>
- #include <sbi/sbi_ecall.h>
- #include <sbi/sbi_ecall_interface.h>
- #include <sbi/sbi_trap.h>
- #include <sbi/sbi_tlb.h>
- static int sbi_ecall_rfence_handler(unsigned long extid, unsigned long funcid,
- const struct sbi_trap_regs *regs,
- unsigned long *out_val,
- struct sbi_trap_info *out_trap)
- {
- int ret = 0;
- unsigned long vmid;
- struct sbi_tlb_info tlb_info;
- u32 source_hart = current_hartid();
- if (funcid >= SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID &&
- funcid <= SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA)
- if (!misa_extension('H'))
- return SBI_ENOTSUPP;
- switch (funcid) {
- case SBI_EXT_RFENCE_REMOTE_FENCE_I:
- SBI_TLB_INFO_INIT(&tlb_info, 0, 0, 0, 0,
- 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_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_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_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_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_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_local_sfence_vma_asid, source_hart);
- ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
- break;
- default:
- ret = SBI_ENOTSUPP;
- };
- return ret;
- }
- struct sbi_ecall_extension ecall_rfence = {
- .extid_start = SBI_EXT_RFENCE,
- .extid_end = SBI_EXT_RFENCE,
- .handle = sbi_ecall_rfence_handler,
- };
|