sbi_ecall_rfence.c 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2020 Western Digital Corporation or its affiliates.
  5. *
  6. * Authors:
  7. * Anup Patel <anup.patel@wdc.com>
  8. * Atish Patra <atish.patra@wdc.com>
  9. */
  10. #include <sbi/riscv_asm.h>
  11. #include <sbi/sbi_error.h>
  12. #include <sbi/sbi_ecall.h>
  13. #include <sbi/sbi_ecall_interface.h>
  14. #include <sbi/sbi_trap.h>
  15. #include <sbi/sbi_tlb.h>
  16. static int sbi_ecall_rfence_handler(unsigned long extid, unsigned long funcid,
  17. const struct sbi_trap_regs *regs,
  18. unsigned long *out_val,
  19. struct sbi_trap_info *out_trap)
  20. {
  21. int ret = 0;
  22. unsigned long vmid;
  23. struct sbi_tlb_info tlb_info;
  24. u32 source_hart = current_hartid();
  25. if (funcid >= SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID &&
  26. funcid <= SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA)
  27. if (!misa_extension('H'))
  28. return SBI_ENOTSUPP;
  29. switch (funcid) {
  30. case SBI_EXT_RFENCE_REMOTE_FENCE_I:
  31. SBI_TLB_INFO_INIT(&tlb_info, 0, 0, 0, 0,
  32. sbi_tlb_local_fence_i, source_hart);
  33. ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
  34. break;
  35. case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA:
  36. SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, 0,
  37. sbi_tlb_local_hfence_gvma, source_hart);
  38. ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
  39. break;
  40. case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID:
  41. SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, regs->a4,
  42. sbi_tlb_local_hfence_gvma_vmid,
  43. source_hart);
  44. ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
  45. break;
  46. case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA:
  47. vmid = (csr_read(CSR_HGATP) & HGATP_VMID_MASK);
  48. vmid = vmid >> HGATP_VMID_SHIFT;
  49. SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, vmid,
  50. sbi_tlb_local_hfence_vvma, source_hart);
  51. ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
  52. break;
  53. case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID:
  54. vmid = (csr_read(CSR_HGATP) & HGATP_VMID_MASK);
  55. vmid = vmid >> HGATP_VMID_SHIFT;
  56. SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, regs->a4,
  57. vmid, sbi_tlb_local_hfence_vvma_asid,
  58. source_hart);
  59. ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
  60. break;
  61. case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA:
  62. SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, 0, 0,
  63. sbi_tlb_local_sfence_vma, source_hart);
  64. ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
  65. break;
  66. case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID:
  67. SBI_TLB_INFO_INIT(&tlb_info, regs->a2, regs->a3, regs->a4, 0,
  68. sbi_tlb_local_sfence_vma_asid, source_hart);
  69. ret = sbi_tlb_request(regs->a0, regs->a1, &tlb_info);
  70. break;
  71. default:
  72. ret = SBI_ENOTSUPP;
  73. };
  74. return ret;
  75. }
  76. struct sbi_ecall_extension ecall_rfence = {
  77. .extid_start = SBI_EXT_RFENCE,
  78. .extid_end = SBI_EXT_RFENCE,
  79. .handle = sbi_ecall_rfence_handler,
  80. };