Home | History | Annotate | Line # | Download | only in amdkfd
      1 /*	$NetBSD: kfd_dbgmgr.h,v 1.3 2021/12/18 23:44:59 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2014 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  */
     25 
     26 #ifndef KFD_DBGMGR_H_
     27 #define KFD_DBGMGR_H_
     28 
     29 #include "kfd_priv.h"
     30 
     31 /* must align with hsakmttypes definition */
     32 #pragma pack(push, 4)
     33 
     34 enum HSA_DBG_WAVEOP {
     35 	HSA_DBG_WAVEOP_HALT = 1,   /* Halts a wavefront */
     36 	HSA_DBG_WAVEOP_RESUME = 2, /* Resumes a wavefront */
     37 	HSA_DBG_WAVEOP_KILL = 3,   /* Kills a wavefront */
     38 	HSA_DBG_WAVEOP_DEBUG = 4,  /* Causes wavefront to enter dbg mode */
     39 	HSA_DBG_WAVEOP_TRAP = 5,   /* Causes wavefront to take a trap */
     40 	HSA_DBG_NUM_WAVEOP = 5,
     41 	HSA_DBG_MAX_WAVEOP = 0xFFFFFFFF
     42 };
     43 
     44 enum HSA_DBG_WAVEMODE {
     45 	/* send command to a single wave */
     46 	HSA_DBG_WAVEMODE_SINGLE = 0,
     47 	/*
     48 	 * Broadcast to all wavefronts of all processes is not
     49 	 * supported for HSA user mode
     50 	 */
     51 
     52 	/* send to waves within current process */
     53 	HSA_DBG_WAVEMODE_BROADCAST_PROCESS = 2,
     54 	/* send to waves within current process on CU  */
     55 	HSA_DBG_WAVEMODE_BROADCAST_PROCESS_CU = 3,
     56 	HSA_DBG_NUM_WAVEMODE = 3,
     57 	HSA_DBG_MAX_WAVEMODE = 0xFFFFFFFF
     58 };
     59 
     60 enum HSA_DBG_WAVEMSG_TYPE {
     61 	HSA_DBG_WAVEMSG_AUTO = 0,
     62 	HSA_DBG_WAVEMSG_USER = 1,
     63 	HSA_DBG_WAVEMSG_ERROR = 2,
     64 	HSA_DBG_NUM_WAVEMSG,
     65 	HSA_DBG_MAX_WAVEMSG = 0xFFFFFFFF
     66 };
     67 
     68 enum HSA_DBG_WATCH_MODE {
     69 	HSA_DBG_WATCH_READ = 0,		/* Read operations only */
     70 	HSA_DBG_WATCH_NONREAD = 1,	/* Write or Atomic operations only */
     71 	HSA_DBG_WATCH_ATOMIC = 2,	/* Atomic Operations only */
     72 	HSA_DBG_WATCH_ALL = 3,		/* Read, Write or Atomic operations */
     73 	HSA_DBG_WATCH_NUM,
     74 	HSA_DBG_WATCH_SIZE = 0xFFFFFFFF
     75 };
     76 
     77 /* This structure is hardware specific and may change in the future */
     78 struct HsaDbgWaveMsgAMDGen2 {
     79 	union {
     80 		struct ui32 {
     81 			uint32_t UserData:8;	/* user data */
     82 			uint32_t ShaderArray:1;	/* Shader array */
     83 			uint32_t Priv:1;	/* Privileged */
     84 			uint32_t Reserved0:4;	/* Reserved, should be 0 */
     85 			uint32_t WaveId:4;	/* wave id */
     86 			uint32_t SIMD:2;	/* SIMD id */
     87 			uint32_t HSACU:4;	/* Compute unit */
     88 			uint32_t ShaderEngine:2;/* Shader engine */
     89 			uint32_t MessageType:2;	/* see HSA_DBG_WAVEMSG_TYPE */
     90 			uint32_t Reserved1:4;	/* Reserved, should be 0 */
     91 		} ui32;
     92 		uint32_t Value;
     93 	};
     94 	uint32_t Reserved2;
     95 };
     96 
     97 union HsaDbgWaveMessageAMD {
     98 	struct HsaDbgWaveMsgAMDGen2 WaveMsgInfoGen2;
     99 	/* for future HsaDbgWaveMsgAMDGen3; */
    100 };
    101 
    102 struct HsaDbgWaveMessage {
    103 	void *MemoryVA;		/* ptr to associated host-accessible data */
    104 	union HsaDbgWaveMessageAMD DbgWaveMsg;
    105 };
    106 
    107 /*
    108  * TODO: This definitions to be MOVED to kfd_event, once it is implemented.
    109  *
    110  * HSA sync primitive, Event and HW Exception notification API definitions.
    111  * The API functions allow the runtime to define a so-called sync-primitive,
    112  * a SW object combining a user-mode provided "syncvar" and a scheduler event
    113  * that can be signaled through a defined GPU interrupt. A syncvar is
    114  * a process virtual memory location of a certain size that can be accessed
    115  * by CPU and GPU shader code within the process to set and query the content
    116  * within that memory. The definition of the content is determined by the HSA
    117  * runtime and potentially GPU shader code interfacing with the HSA runtime.
    118  * The syncvar values may be commonly written through an PM4 WRITE_DATA packet
    119  * in the user mode instruction stream. The OS scheduler event is typically
    120  * associated and signaled by an interrupt issued by the GPU, but other HSA
    121  * system interrupt conditions from other HW (e.g. IOMMUv2) may be surfaced
    122  * by the KFD by this mechanism, too.
    123  */
    124 
    125 /* these are the new definitions for events */
    126 enum HSA_EVENTTYPE {
    127 	HSA_EVENTTYPE_SIGNAL = 0,	/* user-mode generated GPU signal */
    128 	HSA_EVENTTYPE_NODECHANGE = 1,	/* HSA node change (attach/detach) */
    129 	HSA_EVENTTYPE_DEVICESTATECHANGE = 2,	/* HSA device state change
    130 						 * (start/stop)
    131 						 */
    132 	HSA_EVENTTYPE_HW_EXCEPTION = 3,	/* GPU shader exception event */
    133 	HSA_EVENTTYPE_SYSTEM_EVENT = 4,	/* GPU SYSCALL with parameter info */
    134 	HSA_EVENTTYPE_DEBUG_EVENT = 5,	/* GPU signal for debugging */
    135 	HSA_EVENTTYPE_PROFILE_EVENT = 6,/* GPU signal for profiling */
    136 	HSA_EVENTTYPE_QUEUE_EVENT = 7,	/* GPU signal queue idle state
    137 					 * (EOP pm4)
    138 					 */
    139 	/* ...  */
    140 	HSA_EVENTTYPE_MAXID,
    141 	HSA_EVENTTYPE_TYPE_SIZE = 0xFFFFFFFF
    142 };
    143 
    144 /* Sub-definitions for various event types: Syncvar */
    145 struct HsaSyncVar {
    146 	union SyncVar {
    147 		void *UserData;	/* pointer to user mode data */
    148 		uint64_t UserDataPtrValue; /* 64bit compatibility of value */
    149 	} SyncVar;
    150 	uint64_t SyncVarSize;
    151 };
    152 
    153 /* Sub-definitions for various event types: NodeChange */
    154 
    155 enum HSA_EVENTTYPE_NODECHANGE_FLAGS {
    156 	HSA_EVENTTYPE_NODECHANGE_ADD = 0,
    157 	HSA_EVENTTYPE_NODECHANGE_REMOVE = 1,
    158 	HSA_EVENTTYPE_NODECHANGE_SIZE = 0xFFFFFFFF
    159 };
    160 
    161 struct HsaNodeChange {
    162 	/* HSA node added/removed on the platform */
    163 	enum HSA_EVENTTYPE_NODECHANGE_FLAGS Flags;
    164 };
    165 
    166 /* Sub-definitions for various event types: DeviceStateChange */
    167 enum HSA_EVENTTYPE_DEVICESTATECHANGE_FLAGS {
    168 	/* device started (and available) */
    169 	HSA_EVENTTYPE_DEVICESTATUSCHANGE_START = 0,
    170 	/* device stopped (i.e. unavailable) */
    171 	HSA_EVENTTYPE_DEVICESTATUSCHANGE_STOP = 1,
    172 	HSA_EVENTTYPE_DEVICESTATUSCHANGE_SIZE = 0xFFFFFFFF
    173 };
    174 
    175 enum HSA_DEVICE {
    176 	HSA_DEVICE_CPU = 0,
    177 	HSA_DEVICE_GPU = 1,
    178 	MAX_HSA_DEVICE = 2
    179 };
    180 
    181 struct HsaDeviceStateChange {
    182 	uint32_t NodeId;	/* F-NUMA node that contains the device */
    183 	enum HSA_DEVICE Device;	/* device type: GPU or CPU */
    184 	enum HSA_EVENTTYPE_DEVICESTATECHANGE_FLAGS Flags; /* event flags */
    185 };
    186 
    187 struct HsaEventData {
    188 	enum HSA_EVENTTYPE EventType; /* event type */
    189 	union EventData {
    190 		/*
    191 		 * return data associated with HSA_EVENTTYPE_SIGNAL
    192 		 * and other events
    193 		 */
    194 		struct HsaSyncVar SyncVar;
    195 
    196 		/* data associated with HSA_EVENTTYPE_NODE_CHANGE */
    197 		struct HsaNodeChange NodeChangeState;
    198 
    199 		/* data associated with HSA_EVENTTYPE_DEVICE_STATE_CHANGE */
    200 		struct HsaDeviceStateChange DeviceState;
    201 	} EventData;
    202 
    203 	/* the following data entries are internal to the KFD & thunk itself */
    204 
    205 	/* internal thunk store for Event data (OsEventHandle) */
    206 	uint64_t HWData1;
    207 	/* internal thunk store for Event data (HWAddress) */
    208 	uint64_t HWData2;
    209 	/* internal thunk store for Event data (HWData) */
    210 	uint32_t HWData3;
    211 };
    212 
    213 struct HsaEventDescriptor {
    214 	/* event type to allocate */
    215 	enum HSA_EVENTTYPE EventType;
    216 	/* H-NUMA node containing GPU device that is event source */
    217 	uint32_t NodeId;
    218 	/* pointer to user mode syncvar data, syncvar->UserDataPtrValue
    219 	 * may be NULL
    220 	 */
    221 	struct HsaSyncVar SyncVar;
    222 };
    223 
    224 struct HsaEvent {
    225 	uint32_t EventId;
    226 	struct HsaEventData EventData;
    227 };
    228 
    229 #pragma pack(pop)
    230 
    231 enum DBGDEV_TYPE {
    232 	DBGDEV_TYPE_ILLEGAL = 0,
    233 	DBGDEV_TYPE_NODIQ = 1,
    234 	DBGDEV_TYPE_DIQ = 2,
    235 	DBGDEV_TYPE_TEST = 3
    236 };
    237 
    238 struct dbg_address_watch_info {
    239 	struct kfd_process *process;
    240 	enum HSA_DBG_WATCH_MODE *watch_mode;
    241 	uint64_t *watch_address;
    242 	uint64_t *watch_mask;
    243 	struct HsaEvent *watch_event;
    244 	uint32_t num_watch_points;
    245 };
    246 
    247 struct dbg_wave_control_info {
    248 	struct kfd_process *process;
    249 	uint32_t trapId;
    250 	enum HSA_DBG_WAVEOP operand;
    251 	enum HSA_DBG_WAVEMODE mode;
    252 	struct HsaDbgWaveMessage dbgWave_msg;
    253 };
    254 
    255 struct kfd_dbgdev {
    256 
    257 	/* The device that owns this data. */
    258 	struct kfd_dev *dev;
    259 
    260 	/* kernel queue for DIQ */
    261 	struct kernel_queue *kq;
    262 
    263 	/* a pointer to the pqm of the calling process */
    264 	struct process_queue_manager *pqm;
    265 
    266 	/* type of debug device ( DIQ, non DIQ, etc. ) */
    267 	enum DBGDEV_TYPE type;
    268 
    269 	/* virtualized function pointers to device dbg */
    270 	int (*dbgdev_register)(struct kfd_dbgdev *dbgdev);
    271 	int (*dbgdev_unregister)(struct kfd_dbgdev *dbgdev);
    272 	int (*dbgdev_address_watch)(struct kfd_dbgdev *dbgdev,
    273 				struct dbg_address_watch_info *adw_info);
    274 	int (*dbgdev_wave_control)(struct kfd_dbgdev *dbgdev,
    275 				struct dbg_wave_control_info *wac_info);
    276 
    277 };
    278 
    279 struct kfd_dbgmgr {
    280 	unsigned int pasid;
    281 	struct kfd_dev *dev;
    282 	struct kfd_dbgdev *dbgdev;
    283 };
    284 
    285 /* prototypes for debug manager functions */
    286 struct mutex *kfd_get_dbgmgr_mutex(void);
    287 void kfd_dbgmgr_destroy(struct kfd_dbgmgr *pmgr);
    288 bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev);
    289 long kfd_dbgmgr_register(struct kfd_dbgmgr *pmgr, struct kfd_process *p);
    290 long kfd_dbgmgr_unregister(struct kfd_dbgmgr *pmgr, struct kfd_process *p);
    291 long kfd_dbgmgr_wave_control(struct kfd_dbgmgr *pmgr,
    292 				struct dbg_wave_control_info *wac_info);
    293 long kfd_dbgmgr_address_watch(struct kfd_dbgmgr *pmgr,
    294 			struct dbg_address_watch_info *adw_info);
    295 #endif /* KFD_DBGMGR_H_ */
    296