1 /* Target used to communicate with the AMD Debugger API. 2 3 Copyright (C) 2019-2024 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #ifndef AMD_DBGAPI_TARGET_H 21 #define AMD_DBGAPI_TARGET_H 1 22 23 #include "gdbsupport/observable.h" 24 25 #include <amd-dbgapi/amd-dbgapi.h> 26 27 struct inferior; 28 29 namespace detail 30 { 31 32 template <typename T> 33 using is_amd_dbgapi_handle 34 = gdb::Or<std::is_same<T, amd_dbgapi_address_class_id_t>, 35 std::is_same<T, amd_dbgapi_address_space_id_t>, 36 std::is_same<T, amd_dbgapi_architecture_id_t>, 37 std::is_same<T, amd_dbgapi_agent_id_t>, 38 std::is_same<T, amd_dbgapi_breakpoint_id_t>, 39 std::is_same<T, amd_dbgapi_code_object_id_t>, 40 std::is_same<T, amd_dbgapi_dispatch_id_t>, 41 std::is_same<T, amd_dbgapi_displaced_stepping_id_t>, 42 std::is_same<T, amd_dbgapi_event_id_t>, 43 std::is_same<T, amd_dbgapi_process_id_t>, 44 std::is_same<T, amd_dbgapi_queue_id_t>, 45 std::is_same<T, amd_dbgapi_register_class_id_t>, 46 std::is_same<T, amd_dbgapi_register_id_t>, 47 std::is_same<T, amd_dbgapi_watchpoint_id_t>, 48 std::is_same<T, amd_dbgapi_wave_id_t>>; 49 50 } /* namespace detail */ 51 52 /* Get the token of amd-dbgapi's inferior_created observer. */ 53 54 const gdb::observers::token & 55 get_amd_dbgapi_target_inferior_created_observer_token (); 56 57 /* Comparison operators for amd-dbgapi handle types. */ 58 59 template <typename T, 60 typename = gdb::Requires<detail::is_amd_dbgapi_handle<T>>> 61 bool 62 operator== (const T &lhs, const T &rhs) 63 { 64 return lhs.handle == rhs.handle; 65 } 66 67 template <typename T, 68 typename = gdb::Requires<detail::is_amd_dbgapi_handle<T>>> 69 bool 70 operator!= (const T &lhs, const T &rhs) 71 { 72 return !(lhs == rhs); 73 } 74 75 /* Return true if the given ptid is a GPU thread (wave) ptid. */ 76 77 static inline bool 78 ptid_is_gpu (ptid_t ptid) 79 { 80 /* FIXME: Currently using values that are known not to conflict with other 81 processes to indicate if it is a GPU thread. ptid.pid 1 is the init 82 process and is the only process that could have a ptid.lwp of 1. The init 83 process cannot have a GPU. No other process can have a ptid.lwp of 1. 84 The GPU wave ID is stored in the ptid.tid. */ 85 return ptid.pid () != 1 && ptid.lwp () == 1; 86 } 87 88 /* Return INF's amd_dbgapi process id. */ 89 90 amd_dbgapi_process_id_t get_amd_dbgapi_process_id (inferior *inf); 91 92 /* Get the amd-dbgapi wave id for PTID. */ 93 94 static inline amd_dbgapi_wave_id_t 95 get_amd_dbgapi_wave_id (ptid_t ptid) 96 { 97 gdb_assert (ptid_is_gpu (ptid)); 98 return amd_dbgapi_wave_id_t { 99 static_cast<decltype (amd_dbgapi_wave_id_t::handle)> (ptid.tid ()) 100 }; 101 } 102 103 /* Get the textual version of STATUS. 104 105 Always returns non-nullptr, and asserts that STATUS has a valid value. */ 106 107 static inline const char * 108 get_status_string (amd_dbgapi_status_t status) 109 { 110 const char *ret; 111 status = amd_dbgapi_get_status_string (status, &ret); 112 gdb_assert (status == AMD_DBGAPI_STATUS_SUCCESS); 113 return ret; 114 } 115 116 #endif /* AMD_DBGAPI_TARGET_H */ 117