sbi_emulate_csr.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2019 Western Digital Corporation or its affiliates.
  5. *
  6. * Authors:
  7. * Anup Patel <anup.patel@wdc.com>
  8. */
  9. #include <sbi/riscv_asm.h>
  10. #include <sbi/riscv_encoding.h>
  11. #include <sbi/sbi_bits.h>
  12. #include <sbi/sbi_console.h>
  13. #include <sbi/sbi_emulate_csr.h>
  14. #include <sbi/sbi_error.h>
  15. #include <sbi/sbi_timer.h>
  16. int sbi_emulate_csr_read(int csr_num,
  17. u32 hartid, ulong mstatus,
  18. struct sbi_scratch *scratch,
  19. ulong *csr_val)
  20. {
  21. ulong cen = -1UL;
  22. if (EXTRACT_FIELD(mstatus, MSTATUS_MPP) == PRV_U)
  23. cen = csr_read(CSR_SCOUNTEREN);
  24. switch (csr_num) {
  25. case CSR_CYCLE:
  26. if (!((cen >> (CSR_CYCLE - CSR_CYCLE)) & 1))
  27. return -1;
  28. *csr_val = csr_read(CSR_MCYCLE);
  29. break;
  30. case CSR_TIME:
  31. if (!((cen >> (CSR_TIME - CSR_CYCLE)) & 1))
  32. return -1;
  33. *csr_val = sbi_timer_value(scratch);
  34. break;
  35. case CSR_INSTRET:
  36. if (!((cen >> (CSR_INSTRET - CSR_CYCLE)) & 1))
  37. return -1;
  38. *csr_val = csr_read(CSR_MINSTRET);
  39. break;
  40. case CSR_MHPMCOUNTER3:
  41. if (!((cen >> (3 + CSR_MHPMCOUNTER3 - CSR_MHPMCOUNTER3)) & 1))
  42. return -1;
  43. *csr_val = csr_read(CSR_MHPMCOUNTER3);
  44. break;
  45. case CSR_MHPMCOUNTER4:
  46. if (!((cen >> (3 + CSR_MHPMCOUNTER4 - CSR_MHPMCOUNTER3)) & 1))
  47. return -1;
  48. *csr_val = csr_read(CSR_MHPMCOUNTER4);
  49. break;
  50. #if __riscv_xlen == 32
  51. case CSR_CYCLEH:
  52. if (!((cen >> (CSR_CYCLE - CSR_CYCLE)) & 1))
  53. return -1;
  54. *csr_val = csr_read(CSR_MCYCLEH);
  55. break;
  56. case CSR_TIMEH:
  57. if (!((cen >> (CSR_TIME - CSR_CYCLE)) & 1))
  58. return -1;
  59. *csr_val = sbi_timer_value(scratch) >> 32;
  60. break;
  61. case CSR_INSTRETH:
  62. if (!((cen >> (CSR_INSTRET - CSR_CYCLE)) & 1))
  63. return -1;
  64. *csr_val = csr_read(CSR_MINSTRETH);
  65. break;
  66. case CSR_MHPMCOUNTER3H:
  67. if (!((cen >> (3 + CSR_MHPMCOUNTER3 - CSR_MHPMCOUNTER3)) & 1))
  68. return -1;
  69. *csr_val = csr_read(CSR_MHPMCOUNTER3H);
  70. break;
  71. case CSR_MHPMCOUNTER4H:
  72. if (!((cen >> (3 + CSR_MHPMCOUNTER4 - CSR_MHPMCOUNTER3)) & 1))
  73. return -1;
  74. *csr_val = csr_read(CSR_MHPMCOUNTER4H);
  75. break;
  76. #endif
  77. case CSR_MHPMEVENT3:
  78. *csr_val = csr_read(CSR_MHPMEVENT3);
  79. break;
  80. case CSR_MHPMEVENT4:
  81. *csr_val = csr_read(CSR_MHPMEVENT4);
  82. break;
  83. default:
  84. sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n",
  85. __func__, hartid, csr_num);
  86. return SBI_ENOTSUPP;
  87. };
  88. return 0;
  89. }
  90. int sbi_emulate_csr_write(int csr_num,
  91. u32 hartid, ulong mstatus,
  92. struct sbi_scratch *scratch,
  93. ulong csr_val)
  94. {
  95. switch (csr_num) {
  96. case CSR_CYCLE:
  97. csr_write(CSR_MCYCLE, csr_val);
  98. break;
  99. case CSR_INSTRET:
  100. csr_write(CSR_MINSTRET, csr_val);
  101. break;
  102. case CSR_MHPMCOUNTER3:
  103. csr_write(CSR_MHPMCOUNTER3, csr_val);
  104. break;
  105. case CSR_MHPMCOUNTER4:
  106. csr_write(CSR_MHPMCOUNTER4, csr_val);
  107. break;
  108. #if __riscv_xlen == 32
  109. case CSR_CYCLEH:
  110. csr_write(CSR_MCYCLEH, csr_val);
  111. break;
  112. case CSR_INSTRETH:
  113. csr_write(CSR_MINSTRETH, csr_val);
  114. break;
  115. case CSR_MHPMCOUNTER3H:
  116. csr_write(CSR_MHPMCOUNTER3H, csr_val);
  117. break;
  118. case CSR_MHPMCOUNTER4H:
  119. csr_write(CSR_MHPMCOUNTER4H, csr_val);
  120. break;
  121. #endif
  122. case CSR_MHPMEVENT3:
  123. csr_write(CSR_MHPMEVENT3, csr_val);
  124. break;
  125. case CSR_MHPMEVENT4:
  126. csr_write(CSR_MHPMEVENT4, csr_val);
  127. break;
  128. default:
  129. sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n",
  130. __func__, hartid, csr_num);
  131. return SBI_ENOTSUPP;
  132. };
  133. return 0;
  134. }