Skip to content

Commit 7ea0468

Browse files
committed
accel/amdxdna: Support firmware debug buffer
To collect firmware debug information, the userspace application allocates a AMDXDNA_BO_DEV buffer object through DRM_IOCTL_AMDXDNA_CREATE_BO. Then it associates the buffer with the hardware context through DRM_IOCTL_AMDXDNA_CONFIG_HWCTX which requests firmware to bind the buffer through a mailbox command. The firmware then writes the debug data into this buffer. The buffer can be mapped into userspace so that applications can retrieve and analyze the firmware debug information. Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org> Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> Link: https://lore.kernel.org/r/20251016203016.819441-1-lizhi.hou@amd.com
1 parent fb4f1cb commit 7ea0468

14 files changed

Lines changed: 226 additions & 14 deletions

drivers/accel/amdxdna/TODO

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
- Add debugfs support
2-
- Add debug BO support

drivers/accel/amdxdna/aie2_ctx.c

Lines changed: 109 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,10 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size)
226226
}
227227

228228
static int
229-
aie2_sched_nocmd_resp_handler(void *handle, void __iomem *data, size_t size)
229+
aie2_sched_drvcmd_resp_handler(void *handle, void __iomem *data, size_t size)
230230
{
231231
struct amdxdna_sched_job *job = handle;
232232
int ret = 0;
233-
u32 status;
234233

235234
if (unlikely(!data))
236235
goto out;
@@ -240,8 +239,7 @@ aie2_sched_nocmd_resp_handler(void *handle, void __iomem *data, size_t size)
240239
goto out;
241240
}
242241

243-
status = readl(data);
244-
XDNA_DBG(job->hwctx->client->xdna, "Resp status 0x%x", status);
242+
job->drv_cmd->result = readl(data);
245243

246244
out:
247245
aie2_sched_notify(job);
@@ -314,8 +312,18 @@ aie2_sched_job_run(struct drm_sched_job *sched_job)
314312
kref_get(&job->refcnt);
315313
fence = dma_fence_get(job->fence);
316314

317-
if (unlikely(!cmd_abo)) {
318-
ret = aie2_sync_bo(hwctx, job, aie2_sched_nocmd_resp_handler);
315+
if (job->drv_cmd) {
316+
switch (job->drv_cmd->opcode) {
317+
case SYNC_DEBUG_BO:
318+
ret = aie2_sync_bo(hwctx, job, aie2_sched_drvcmd_resp_handler);
319+
break;
320+
case ATTACH_DEBUG_BO:
321+
ret = aie2_config_debug_bo(hwctx, job, aie2_sched_drvcmd_resp_handler);
322+
break;
323+
default:
324+
ret = -EINVAL;
325+
break;
326+
}
319327
goto out;
320328
}
321329

@@ -766,6 +774,74 @@ static int aie2_hwctx_cu_config(struct amdxdna_hwctx *hwctx, void *buf, u32 size
766774
return ret;
767775
}
768776

777+
static void aie2_cmd_wait(struct amdxdna_hwctx *hwctx, u64 seq)
778+
{
779+
struct dma_fence *out_fence = aie2_cmd_get_out_fence(hwctx, seq);
780+
781+
if (!out_fence) {
782+
XDNA_ERR(hwctx->client->xdna, "Failed to get fence");
783+
return;
784+
}
785+
786+
dma_fence_wait_timeout(out_fence, false, MAX_SCHEDULE_TIMEOUT);
787+
dma_fence_put(out_fence);
788+
}
789+
790+
static int aie2_hwctx_cfg_debug_bo(struct amdxdna_hwctx *hwctx, u32 bo_hdl,
791+
bool attach)
792+
{
793+
struct amdxdna_client *client = hwctx->client;
794+
struct amdxdna_dev *xdna = client->xdna;
795+
struct amdxdna_drv_cmd cmd = { 0 };
796+
struct amdxdna_gem_obj *abo;
797+
u64 seq;
798+
int ret;
799+
800+
abo = amdxdna_gem_get_obj(client, bo_hdl, AMDXDNA_BO_DEV);
801+
if (!abo) {
802+
XDNA_ERR(xdna, "Get bo %d failed", bo_hdl);
803+
return -EINVAL;
804+
}
805+
806+
if (attach) {
807+
if (abo->assigned_hwctx != AMDXDNA_INVALID_CTX_HANDLE) {
808+
ret = -EBUSY;
809+
goto put_obj;
810+
}
811+
cmd.opcode = ATTACH_DEBUG_BO;
812+
} else {
813+
if (abo->assigned_hwctx != hwctx->id) {
814+
ret = -EINVAL;
815+
goto put_obj;
816+
}
817+
cmd.opcode = DETACH_DEBUG_BO;
818+
}
819+
820+
ret = amdxdna_cmd_submit(client, &cmd, AMDXDNA_INVALID_BO_HANDLE,
821+
&bo_hdl, 1, hwctx->id, &seq);
822+
if (ret) {
823+
XDNA_ERR(xdna, "Submit command failed");
824+
goto put_obj;
825+
}
826+
827+
aie2_cmd_wait(hwctx, seq);
828+
if (cmd.result) {
829+
XDNA_ERR(xdna, "Response failure 0x%x", cmd.result);
830+
goto put_obj;
831+
}
832+
833+
if (attach)
834+
abo->assigned_hwctx = hwctx->id;
835+
else
836+
abo->assigned_hwctx = AMDXDNA_INVALID_CTX_HANDLE;
837+
838+
XDNA_DBG(xdna, "Config debug BO %d to %s", bo_hdl, hwctx->name);
839+
840+
put_obj:
841+
amdxdna_gem_put_obj(abo);
842+
return ret;
843+
}
844+
769845
int aie2_hwctx_config(struct amdxdna_hwctx *hwctx, u32 type, u64 value, void *buf, u32 size)
770846
{
771847
struct amdxdna_dev *xdna = hwctx->client->xdna;
@@ -775,14 +851,40 @@ int aie2_hwctx_config(struct amdxdna_hwctx *hwctx, u32 type, u64 value, void *bu
775851
case DRM_AMDXDNA_HWCTX_CONFIG_CU:
776852
return aie2_hwctx_cu_config(hwctx, buf, size);
777853
case DRM_AMDXDNA_HWCTX_ASSIGN_DBG_BUF:
854+
return aie2_hwctx_cfg_debug_bo(hwctx, (u32)value, true);
778855
case DRM_AMDXDNA_HWCTX_REMOVE_DBG_BUF:
779-
return -EOPNOTSUPP;
856+
return aie2_hwctx_cfg_debug_bo(hwctx, (u32)value, false);
780857
default:
781858
XDNA_DBG(xdna, "Not supported type %d", type);
782859
return -EOPNOTSUPP;
783860
}
784861
}
785862

863+
int aie2_hwctx_sync_debug_bo(struct amdxdna_hwctx *hwctx, u32 debug_bo_hdl)
864+
{
865+
struct amdxdna_client *client = hwctx->client;
866+
struct amdxdna_dev *xdna = client->xdna;
867+
struct amdxdna_drv_cmd cmd = { 0 };
868+
u64 seq;
869+
int ret;
870+
871+
cmd.opcode = SYNC_DEBUG_BO;
872+
ret = amdxdna_cmd_submit(client, &cmd, AMDXDNA_INVALID_BO_HANDLE,
873+
&debug_bo_hdl, 1, hwctx->id, &seq);
874+
if (ret) {
875+
XDNA_ERR(xdna, "Submit command failed");
876+
return ret;
877+
}
878+
879+
aie2_cmd_wait(hwctx, seq);
880+
if (cmd.result) {
881+
XDNA_ERR(xdna, "Response failure 0x%x", cmd.result);
882+
return ret;
883+
}
884+
885+
return 0;
886+
}
887+
786888
static int aie2_populate_range(struct amdxdna_gem_obj *abo)
787889
{
788890
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);

drivers/accel/amdxdna/aie2_message.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ int aie2_sync_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
749749
int ret = 0;
750750

751751
req.src_addr = 0;
752-
req.dst_addr = abo->mem.dev_addr - hwctx->client->dev_heap->mem.dev_addr;
752+
req.dst_addr = amdxdna_dev_bo_offset(abo);
753753
req.size = abo->mem.size;
754754

755755
/* Device to Host */
@@ -773,3 +773,32 @@ int aie2_sync_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
773773

774774
return 0;
775775
}
776+
777+
int aie2_config_debug_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
778+
int (*notify_cb)(void *, void __iomem *, size_t))
779+
{
780+
struct mailbox_channel *chann = hwctx->priv->mbox_chann;
781+
struct amdxdna_gem_obj *abo = to_xdna_obj(job->bos[0]);
782+
struct amdxdna_dev *xdna = hwctx->client->xdna;
783+
struct config_debug_bo_req req;
784+
struct xdna_mailbox_msg msg;
785+
786+
if (job->drv_cmd->opcode == ATTACH_DEBUG_BO)
787+
req.config = DEBUG_BO_REGISTER;
788+
else
789+
req.config = DEBUG_BO_UNREGISTER;
790+
791+
req.offset = amdxdna_dev_bo_offset(abo);
792+
req.size = abo->mem.size;
793+
794+
XDNA_DBG(xdna, "offset 0x%llx size 0x%llx config %d",
795+
req.offset, req.size, req.config);
796+
797+
msg.handle = job;
798+
msg.notify_cb = notify_cb;
799+
msg.send_data = (u8 *)&req;
800+
msg.send_size = sizeof(req);
801+
msg.opcode = MSG_OP_CONFIG_DEBUG_BO;
802+
803+
return xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
804+
}

drivers/accel/amdxdna/aie2_msg_priv.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ enum aie2_msg_opcode {
1818
MSG_OP_CONFIG_CU = 0x11,
1919
MSG_OP_CHAIN_EXEC_BUFFER_CF = 0x12,
2020
MSG_OP_CHAIN_EXEC_DPU = 0x13,
21+
MSG_OP_CONFIG_DEBUG_BO = 0x14,
2122
MSG_OP_MAX_XRT_OPCODE,
2223
MSG_OP_SUSPEND = 0x101,
2324
MSG_OP_RESUME = 0x102,
@@ -365,4 +366,21 @@ struct sync_bo_req {
365366
struct sync_bo_resp {
366367
enum aie2_msg_status status;
367368
} __packed;
369+
370+
#define DEBUG_BO_UNREGISTER 0
371+
#define DEBUG_BO_REGISTER 1
372+
struct config_debug_bo_req {
373+
__u64 offset;
374+
__u64 size;
375+
/*
376+
* config operations.
377+
* DEBUG_BO_REGISTER: Register debug buffer
378+
* DEBUG_BO_UNREGISTER: Unregister debug buffer
379+
*/
380+
__u32 config;
381+
} __packed;
382+
383+
struct config_debug_bo_resp {
384+
enum aie2_msg_status status;
385+
} __packed;
368386
#endif /* _AIE2_MSG_PRIV_H_ */

drivers/accel/amdxdna/aie2_pci.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,7 @@ const struct amdxdna_dev_ops aie2_ops = {
10041004
.hwctx_init = aie2_hwctx_init,
10051005
.hwctx_fini = aie2_hwctx_fini,
10061006
.hwctx_config = aie2_hwctx_config,
1007+
.hwctx_sync_debug_bo = aie2_hwctx_sync_debug_bo,
10071008
.cmd_submit = aie2_cmd_submit,
10081009
.hmm_invalidate = aie2_hmm_invalidate,
10091010
.get_array = aie2_get_array,

drivers/accel/amdxdna/aie2_pci.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,14 @@ int aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx *hwctx,
287287
int (*notify_cb)(void *, void __iomem *, size_t));
288288
int aie2_sync_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
289289
int (*notify_cb)(void *, void __iomem *, size_t));
290+
int aie2_config_debug_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
291+
int (*notify_cb)(void *, void __iomem *, size_t));
290292

291293
/* aie2_hwctx.c */
292294
int aie2_hwctx_init(struct amdxdna_hwctx *hwctx);
293295
void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx);
294296
int aie2_hwctx_config(struct amdxdna_hwctx *hwctx, u32 type, u64 value, void *buf, u32 size);
297+
int aie2_hwctx_sync_debug_bo(struct amdxdna_hwctx *hwctx, u32 debug_bo_hdl);
295298
void aie2_hwctx_suspend(struct amdxdna_client *client);
296299
int aie2_hwctx_resume(struct amdxdna_client *client);
297300
int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, u64 *seq);

drivers/accel/amdxdna/amdxdna_ctx.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,38 @@ int amdxdna_drm_config_hwctx_ioctl(struct drm_device *dev, void *data, struct dr
328328
return ret;
329329
}
330330

331+
int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl)
332+
{
333+
struct amdxdna_dev *xdna = client->xdna;
334+
struct amdxdna_hwctx *hwctx;
335+
struct amdxdna_gem_obj *abo;
336+
struct drm_gem_object *gobj;
337+
int ret, idx;
338+
339+
if (!xdna->dev_info->ops->hwctx_sync_debug_bo)
340+
return -EOPNOTSUPP;
341+
342+
gobj = drm_gem_object_lookup(client->filp, debug_bo_hdl);
343+
if (!gobj)
344+
return -EINVAL;
345+
346+
abo = to_xdna_obj(gobj);
347+
guard(mutex)(&xdna->dev_lock);
348+
idx = srcu_read_lock(&client->hwctx_srcu);
349+
hwctx = xa_load(&client->hwctx_xa, abo->assigned_hwctx);
350+
if (!hwctx) {
351+
ret = -EINVAL;
352+
goto unlock_srcu;
353+
}
354+
355+
ret = xdna->dev_info->ops->hwctx_sync_debug_bo(hwctx, debug_bo_hdl);
356+
357+
unlock_srcu:
358+
srcu_read_unlock(&client->hwctx_srcu, idx);
359+
drm_gem_object_put(gobj);
360+
return ret;
361+
}
362+
331363
static void
332364
amdxdna_arg_bos_put(struct amdxdna_sched_job *job)
333365
{
@@ -393,6 +425,7 @@ void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job)
393425
}
394426

395427
int amdxdna_cmd_submit(struct amdxdna_client *client,
428+
struct amdxdna_drv_cmd *drv_cmd,
396429
u32 cmd_bo_hdl, u32 *arg_bo_hdls, u32 arg_bo_cnt,
397430
u32 hwctx_hdl, u64 *seq)
398431
{
@@ -406,15 +439,15 @@ int amdxdna_cmd_submit(struct amdxdna_client *client,
406439
if (!job)
407440
return -ENOMEM;
408441

442+
job->drv_cmd = drv_cmd;
443+
409444
if (cmd_bo_hdl != AMDXDNA_INVALID_BO_HANDLE) {
410445
job->cmd_bo = amdxdna_gem_get_obj(client, cmd_bo_hdl, AMDXDNA_BO_CMD);
411446
if (!job->cmd_bo) {
412447
XDNA_ERR(xdna, "Failed to get cmd bo from %d", cmd_bo_hdl);
413448
ret = -EINVAL;
414449
goto free_job;
415450
}
416-
} else {
417-
job->cmd_bo = NULL;
418451
}
419452

420453
ret = amdxdna_arg_bos_lookup(client, job, arg_bo_hdls, arg_bo_cnt);
@@ -508,7 +541,7 @@ static int amdxdna_drm_submit_execbuf(struct amdxdna_client *client,
508541
}
509542
}
510543

511-
ret = amdxdna_cmd_submit(client, cmd_bo_hdl, arg_bo_hdls,
544+
ret = amdxdna_cmd_submit(client, NULL, cmd_bo_hdl, arg_bo_hdls,
512545
args->arg_count, args->hwctx, &args->seq);
513546
if (ret)
514547
XDNA_DBG(xdna, "Submit cmds failed, ret %d", ret);

drivers/accel/amdxdna/amdxdna_ctx.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,17 @@ struct amdxdna_hwctx {
9595
#define drm_job_to_xdna_job(j) \
9696
container_of(j, struct amdxdna_sched_job, base)
9797

98+
enum amdxdna_job_opcode {
99+
SYNC_DEBUG_BO,
100+
ATTACH_DEBUG_BO,
101+
DETACH_DEBUG_BO,
102+
};
103+
104+
struct amdxdna_drv_cmd {
105+
enum amdxdna_job_opcode opcode;
106+
u32 result;
107+
};
108+
98109
struct amdxdna_sched_job {
99110
struct drm_sched_job base;
100111
struct kref refcnt;
@@ -106,6 +117,7 @@ struct amdxdna_sched_job {
106117
struct dma_fence *out_fence;
107118
bool job_done;
108119
u64 seq;
120+
struct amdxdna_drv_cmd *drv_cmd;
109121
struct amdxdna_gem_obj *cmd_bo;
110122
size_t bo_cnt;
111123
struct drm_gem_object *bos[] __counted_by(bo_cnt);
@@ -143,9 +155,11 @@ void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job);
143155
void amdxdna_hwctx_remove_all(struct amdxdna_client *client);
144156
int amdxdna_hwctx_walk(struct amdxdna_client *client, void *arg,
145157
int (*walk)(struct amdxdna_hwctx *hwctx, void *arg));
158+
int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl);
146159

147160
int amdxdna_cmd_submit(struct amdxdna_client *client,
148-
u32 cmd_bo_hdls, u32 *arg_bo_hdls, u32 arg_bo_cnt,
161+
struct amdxdna_drv_cmd *drv_cmd, u32 cmd_bo_hdls,
162+
u32 *arg_bo_hdls, u32 arg_bo_cnt,
149163
u32 hwctx_hdl, u64 *seq);
150164

151165
int amdxdna_cmd_wait(struct amdxdna_client *client, u32 hwctx_hdl,

drivers/accel/amdxdna/amdxdna_gem.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,9 @@ int amdxdna_drm_sync_bo_ioctl(struct drm_device *dev,
962962
XDNA_DBG(xdna, "Sync bo %d offset 0x%llx, size 0x%llx\n",
963963
args->handle, args->offset, args->size);
964964

965+
if (args->direction == SYNC_DIRECT_FROM_DEVICE)
966+
ret = amdxdna_hwctx_sync_debug_bo(abo->client, args->handle);
967+
965968
put_obj:
966969
drm_gem_object_put(gobj);
967970
return ret;

0 commit comments

Comments
 (0)