kfd_dbgmgr.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright 2014 Advanced Micro Devices, Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. */
  23. #include <linux/types.h>
  24. #include <linux/kernel.h>
  25. #include <linux/log2.h>
  26. #include <linux/sched.h>
  27. #include <linux/slab.h>
  28. #include <linux/device.h>
  29. #include "kfd_priv.h"
  30. #include "cik_regs.h"
  31. #include "kfd_pm4_headers.h"
  32. #include "kfd_pm4_headers_diq.h"
  33. #include "kfd_dbgmgr.h"
  34. #include "kfd_dbgdev.h"
  35. static DEFINE_MUTEX(kfd_dbgmgr_mutex);
  36. struct mutex *kfd_get_dbgmgr_mutex(void)
  37. {
  38. return &kfd_dbgmgr_mutex;
  39. }
  40. static void kfd_dbgmgr_uninitialize(struct kfd_dbgmgr *pmgr)
  41. {
  42. BUG_ON(!pmgr);
  43. kfree(pmgr->dbgdev);
  44. pmgr->dbgdev = NULL;
  45. pmgr->pasid = 0;
  46. pmgr->dev = NULL;
  47. }
  48. void kfd_dbgmgr_destroy(struct kfd_dbgmgr *pmgr)
  49. {
  50. if (pmgr != NULL) {
  51. kfd_dbgmgr_uninitialize(pmgr);
  52. kfree(pmgr);
  53. }
  54. }
  55. bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev)
  56. {
  57. enum DBGDEV_TYPE type = DBGDEV_TYPE_DIQ;
  58. struct kfd_dbgmgr *new_buff;
  59. BUG_ON(pdev == NULL);
  60. BUG_ON(!pdev->init_complete);
  61. new_buff = kfd_alloc_struct(new_buff);
  62. if (!new_buff) {
  63. pr_err("amdkfd: Failed to allocate dbgmgr instance\n");
  64. return false;
  65. }
  66. new_buff->pasid = 0;
  67. new_buff->dev = pdev;
  68. new_buff->dbgdev = kfd_alloc_struct(new_buff->dbgdev);
  69. if (!new_buff->dbgdev) {
  70. pr_err("amdkfd: Failed to allocate dbgdev instance\n");
  71. kfree(new_buff);
  72. return false;
  73. }
  74. /* get actual type of DBGDevice cpsch or not */
  75. if (sched_policy == KFD_SCHED_POLICY_NO_HWS)
  76. type = DBGDEV_TYPE_NODIQ;
  77. kfd_dbgdev_init(new_buff->dbgdev, pdev, type);
  78. *ppmgr = new_buff;
  79. return true;
  80. }
  81. long kfd_dbgmgr_register(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
  82. {
  83. BUG_ON(!p || !pmgr || !pmgr->dbgdev);
  84. if (pmgr->pasid != 0) {
  85. pr_debug("H/W debugger is already active using pasid %d\n",
  86. pmgr->pasid);
  87. return -EBUSY;
  88. }
  89. /* remember pasid */
  90. pmgr->pasid = p->pasid;
  91. /* provide the pqm for diq generation */
  92. pmgr->dbgdev->pqm = &p->pqm;
  93. /* activate the actual registering */
  94. pmgr->dbgdev->dbgdev_register(pmgr->dbgdev);
  95. return 0;
  96. }
  97. long kfd_dbgmgr_unregister(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
  98. {
  99. BUG_ON(!p || !pmgr || !pmgr->dbgdev);
  100. /* Is the requests coming from the already registered process? */
  101. if (pmgr->pasid != p->pasid) {
  102. pr_debug("H/W debugger is not registered by calling pasid %d\n",
  103. p->pasid);
  104. return -EINVAL;
  105. }
  106. pmgr->dbgdev->dbgdev_unregister(pmgr->dbgdev);
  107. pmgr->pasid = 0;
  108. return 0;
  109. }
  110. long kfd_dbgmgr_wave_control(struct kfd_dbgmgr *pmgr,
  111. struct dbg_wave_control_info *wac_info)
  112. {
  113. BUG_ON(!pmgr || !pmgr->dbgdev || !wac_info);
  114. /* Is the requests coming from the already registered process? */
  115. if (pmgr->pasid != wac_info->process->pasid) {
  116. pr_debug("H/W debugger support was not registered for requester pasid %d\n",
  117. wac_info->process->pasid);
  118. return -EINVAL;
  119. }
  120. return (long) pmgr->dbgdev->dbgdev_wave_control(pmgr->dbgdev, wac_info);
  121. }
  122. long kfd_dbgmgr_address_watch(struct kfd_dbgmgr *pmgr,
  123. struct dbg_address_watch_info *adw_info)
  124. {
  125. BUG_ON(!pmgr || !pmgr->dbgdev || !adw_info);
  126. /* Is the requests coming from the already registered process? */
  127. if (pmgr->pasid != adw_info->process->pasid) {
  128. pr_debug("H/W debugger support was not registered for requester pasid %d\n",
  129. adw_info->process->pasid);
  130. return -EINVAL;
  131. }
  132. return (long) pmgr->dbgdev->dbgdev_address_watch(pmgr->dbgdev,
  133. adw_info);
  134. }