sbi_emulate_csr.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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, u32 hartid, ulong mstatus,
  17. struct sbi_scratch *scratch, ulong *csr_val)
  18. {
  19. ulong cen = -1UL;
  20. if (EXTRACT_FIELD(mstatus, MSTATUS_MPP) == PRV_U)
  21. cen = csr_read(CSR_SCOUNTEREN);
  22. switch (csr_num) {
  23. case CSR_CYCLE:
  24. if (!((cen >> (CSR_CYCLE - CSR_CYCLE)) & 1))
  25. return -1;
  26. *csr_val = csr_read(CSR_MCYCLE);
  27. break;
  28. case CSR_TIME:
  29. if (!((cen >> (CSR_TIME - CSR_CYCLE)) & 1))
  30. return -1;
  31. *csr_val = sbi_timer_value(scratch);
  32. break;
  33. case CSR_INSTRET:
  34. if (!((cen >> (CSR_INSTRET - CSR_CYCLE)) & 1))
  35. return -1;
  36. *csr_val = csr_read(CSR_MINSTRET);
  37. break;
  38. case CSR_MHPMCOUNTER3:
  39. if (!((cen >> (3 + CSR_MHPMCOUNTER3 - CSR_MHPMCOUNTER3)) & 1))
  40. return -1;
  41. *csr_val = csr_read(CSR_MHPMCOUNTER3);
  42. break;
  43. case CSR_MHPMCOUNTER4:
  44. if (!((cen >> (3 + CSR_MHPMCOUNTER4 - CSR_MHPMCOUNTER3)) & 1))
  45. return -1;
  46. *csr_val = csr_read(CSR_MHPMCOUNTER4);
  47. break;
  48. #if __riscv_xlen == 32
  49. case CSR_CYCLEH:
  50. if (!((cen >> (CSR_CYCLE - CSR_CYCLE)) & 1))
  51. return -1;
  52. *csr_val = csr_read(CSR_MCYCLEH);
  53. break;
  54. case CSR_TIMEH:
  55. if (!((cen >> (CSR_TIME - CSR_CYCLE)) & 1))
  56. return -1;
  57. *csr_val = sbi_timer_value(scratch) >> 32;
  58. break;
  59. case CSR_INSTRETH:
  60. if (!((cen >> (CSR_INSTRET - CSR_CYCLE)) & 1))
  61. return -1;
  62. *csr_val = csr_read(CSR_MINSTRETH);
  63. break;
  64. case CSR_MHPMCOUNTER3H:
  65. if (!((cen >> (3 + CSR_MHPMCOUNTER3 - CSR_MHPMCOUNTER3)) & 1))
  66. return -1;
  67. *csr_val = csr_read(CSR_MHPMCOUNTER3H);
  68. break;
  69. case CSR_MHPMCOUNTER4H:
  70. if (!((cen >> (3 + CSR_MHPMCOUNTER4 - CSR_MHPMCOUNTER3)) & 1))
  71. return -1;
  72. *csr_val = csr_read(CSR_MHPMCOUNTER4H);
  73. break;
  74. #endif
  75. case CSR_MHPMEVENT3:
  76. *csr_val = csr_read(CSR_MHPMEVENT3);
  77. break;
  78. case CSR_MHPMEVENT4:
  79. *csr_val = csr_read(CSR_MHPMEVENT4);
  80. break;
  81. default:
  82. sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n", __func__,
  83. hartid, csr_num);
  84. return SBI_ENOTSUPP;
  85. };
  86. return 0;
  87. }
  88. int sbi_emulate_csr_write(int csr_num, u32 hartid, ulong mstatus,
  89. struct sbi_scratch *scratch, ulong csr_val)
  90. {
  91. switch (csr_num) {
  92. case CSR_CYCLE:
  93. csr_write(CSR_MCYCLE, csr_val);
  94. break;
  95. case CSR_INSTRET:
  96. csr_write(CSR_MINSTRET, csr_val);
  97. break;
  98. case CSR_MHPMCOUNTER3:
  99. csr_write(CSR_MHPMCOUNTER3, csr_val);
  100. break;
  101. case CSR_MHPMCOUNTER4:
  102. csr_write(CSR_MHPMCOUNTER4, csr_val);
  103. break;
  104. #if __riscv_xlen == 32
  105. case CSR_CYCLEH:
  106. csr_write(CSR_MCYCLEH, csr_val);
  107. break;
  108. case CSR_INSTRETH:
  109. csr_write(CSR_MINSTRETH, csr_val);
  110. break;
  111. case CSR_MHPMCOUNTER3H:
  112. csr_write(CSR_MHPMCOUNTER3H, csr_val);
  113. break;
  114. case CSR_MHPMCOUNTER4H:
  115. csr_write(CSR_MHPMCOUNTER4H, csr_val);
  116. break;
  117. #endif
  118. case CSR_MHPMEVENT3:
  119. csr_write(CSR_MHPMEVENT3, csr_val);
  120. break;
  121. case CSR_MHPMEVENT4:
  122. csr_write(CSR_MHPMEVENT4, csr_val);
  123. break;
  124. default:
  125. sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n", __func__,
  126. hartid, csr_num);
  127. return SBI_ENOTSUPP;
  128. };
  129. return 0;
  130. }