0027-RISC-V-Create-unique-identification-for-SoC-PMU.patch 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. From f0b0e5392bd7bce16c86d4ed3fc66394db16eb7d Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
  3. <[email protected]>
  4. Date: Tue, 16 Nov 2021 15:48:09 +0000
  5. Subject: [PATCH 27/55] RISC-V: Create unique identification for SoC PMU
  6. MIME-Version: 1.0
  7. Content-Type: text/plain; charset=UTF-8
  8. Content-Transfer-Encoding: 8bit
  9. The SBI PMU platform driver did not provide any identification for
  10. perf events matching. This patch introduces a new sysfs file inside the
  11. platform device (soc:pmu/id) for pmu identification.
  12. The identification is a 64-bit value generated as:
  13. [63-32]: mvendorid;
  14. [31]: marchid[MSB];
  15. [30-16]: marchid[15-0];
  16. [15-0]: mimpid[15MSBs];
  17. The CSRs are detailed in the RISC-V privileged spec [1].
  18. The marchid is split in MSB + 15LSBs, due to the MSB being used for
  19. open-source architecture identification.
  20. [1] https://github.com/riscv/riscv-isa-manual
  21. Signed-off-by: João Mário Domingos <[email protected]>
  22. ---
  23. drivers/perf/riscv_pmu_sbi.c | 47 ++++++++++++++++++++++++++++++++++++
  24. 1 file changed, 47 insertions(+)
  25. --- a/drivers/perf/riscv_pmu_sbi.c
  26. +++ b/drivers/perf/riscv_pmu_sbi.c
  27. @@ -1326,6 +1326,46 @@ static struct ctl_table sbi_pmu_sysctl_t
  28. },
  29. };
  30. +static uint64_t pmu_sbi_get_pmu_id(void)
  31. +{
  32. + union sbi_pmu_id {
  33. + uint64_t value;
  34. + struct {
  35. + uint16_t imp:16;
  36. + uint16_t arch:16;
  37. + uint32_t vendor:32;
  38. + };
  39. + } pmuid;
  40. +
  41. + pmuid.value = 0;
  42. + pmuid.vendor = (uint32_t) sbi_get_mvendorid();
  43. + pmuid.arch = (sbi_get_marchid() >> (63 - 15) & (1 << 15)) | (sbi_get_marchid() & 0x7FFF);
  44. + pmuid.imp = (sbi_get_mimpid() >> 16);
  45. +
  46. + return pmuid.value;
  47. +}
  48. +
  49. +static ssize_t pmu_sbi_id_show(struct device *dev,
  50. + struct device_attribute *attr, char *buf)
  51. +{
  52. + int len;
  53. +
  54. + len = sprintf(buf, "0x%llx\n", pmu_sbi_get_pmu_id());
  55. + if (len <= 0)
  56. + dev_err(dev, "mydrv: Invalid sprintf len: %dn", len);
  57. +
  58. + return len;
  59. +}
  60. +
  61. +static DEVICE_ATTR(id, S_IRUGO | S_IWUSR, pmu_sbi_id_show, 0);
  62. +
  63. +static struct attribute *pmu_sbi_attrs[] = {
  64. + &dev_attr_id.attr,
  65. + NULL
  66. +};
  67. +
  68. +ATTRIBUTE_GROUPS(pmu_sbi);
  69. +
  70. static int pmu_sbi_device_probe(struct platform_device *pdev)
  71. {
  72. struct riscv_pmu *pmu = NULL;
  73. @@ -1375,6 +1415,13 @@ static int pmu_sbi_device_probe(struct p
  74. pmu->event_unmapped = pmu_sbi_event_unmapped;
  75. pmu->csr_index = pmu_sbi_csr_index;
  76. + ret = sysfs_create_group(&pdev->dev.kobj, &pmu_sbi_group);
  77. + if (ret) {
  78. + dev_err(&pdev->dev, "sysfs creation failed\n");
  79. + return ret;
  80. + }
  81. + pdev->dev.groups = pmu_sbi_groups;
  82. +
  83. ret = riscv_pm_pmu_register(pmu);
  84. if (ret)
  85. goto out_unregister;