Re: [PATCH v2 RESEND 2/5] drm: panthor: add devcoredump support

Adrian Larumbe
2024-08-22T12:27:40Z

> On 21.08.2024 11:37, Daniel Almeida wrote:
> Dump the GPU state using devcoredump. This is useful for debugging
> purposes.
>
> Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>

Reviewed-by: Adrian Larumbe <adrian.larumbe@collabora.com>

> ---
> drivers/gpu/drm/panthor/Kconfig | 1 +
> drivers/gpu/drm/panthor/Makefile | 1 +
> drivers/gpu/drm/panthor/panthor_dump.c | 376 ++++++++++++++++++++++++
> drivers/gpu/drm/panthor/panthor_dump.h | 21 ++
> drivers/gpu/drm/panthor/panthor_mmu.c | 22 ++
> drivers/gpu/drm/panthor/panthor_mmu.h | 6 +
> drivers/gpu/drm/panthor/panthor_sched.c | 51 +++-
> drivers/gpu/drm/panthor/panthor_sched.h | 10 +
> include/uapi/drm/panthor_drm.h | 124 ++++++++
> 9 files changed, 611 insertions(+), 1 deletion(-)
> create mode 100644 drivers/gpu/drm/panthor/panthor_dump.c
> create mode 100644 drivers/gpu/drm/panthor/panthor_dump.h
>
> diff --git a/drivers/gpu/drm/panthor/Kconfig b/drivers/gpu/drm/panthor/Kconfig
> index 55b40ad07f3b..eeb80d8e8064 100644
> --- a/drivers/gpu/drm/panthor/Kconfig
> +++ b/drivers/gpu/drm/panthor/Kconfig
> @@ -14,6 +14,7 @@ config DRM_PANTHOR
> select IOMMU_IO_PGTABLE_LPAE
> select IOMMU_SUPPORT
> select PM_DEVFREQ
> + select WANT_DEVCOREDUMP
> help
> DRM driver for ARM Mali CSF-based GPUs.
>
> diff --git a/drivers/gpu/drm/panthor/Makefile b/drivers/gpu/drm/panthor/Makefile
> index 15294719b09c..19be24ddf577 100644
> --- a/drivers/gpu/drm/panthor/Makefile
> +++ b/drivers/gpu/drm/panthor/Makefile
> @@ -4,6 +4,7 @@ panthor-y := \
> panthor_devfreq.o \
> panthor_device.o \
> panthor_drv.o \
> + panthor_dump.o \
> panthor_fw.o \
> panthor_gem.o \
> panthor_gpu.o \
> diff --git a/drivers/gpu/drm/panthor/panthor_dump.c b/drivers/gpu/drm/panthor/panthor_dump.c
> new file mode 100644
> index 000000000000..7ec0e21dc7e9
> --- /dev/null
> +++ b/drivers/gpu/drm/panthor/panthor_dump.c
> @@ -0,0 +1,376 @@
> +// SPDX-License-Identifier: GPL-2.0 or MIT
> +/* SPDX-FileCopyrightText: Copyright Collabora 2024 */
> +
> +#include <drm/drm_gem.h>
> +#include <linux/iosys-map.h>
> +#include <linux/devcoredump.h>
> +#include <linux/err.h>
> +#include <linux/vmalloc.h>
> +#include <linux/types.h>
> +#include <uapi/drm/panthor_drm.h>
> +
> +#include "panthor_device.h"
> +#include "panthor_dump.h"
> +#include "panthor_mmu.h"
> +#include "panthor_sched.h"
> +
> +/* A magic value used when starting a new section in the dump */
> +#define PANT_DUMP_MAGIC 0x544e4150 /* PANT */
> +#define PANT_DUMP_MAJOR 1
> +#define PANT_DUMP_MINOR 0
> +
> +/* keep track of where we are in the underlying buffer */
> +struct dump_allocator {
> + u8 *start;
> + u8 *curr;
> + size_t pos;
> + size_t capacity;
> +};
> +
> +struct vm_dump_count {
> + u64 size;
> + u32 vas;
> +};
> +
> +struct queue_count {
> + u32 queues;
> +};
> +
> +struct dump_group_args {
> + struct panthor_device *ptdev;
> + struct dump_allocator *alloc;
> + struct panthor_group *group;
> +};
> +
> +struct dump_va_args {
> + struct panthor_device *ptdev;
> + struct dump_allocator *alloc;
> +};
> +
> +static void *alloc_bytes(struct dump_allocator *alloc, size_t size)
> +{
> + void *ret;
> +
> + if (alloc->pos + size > alloc->capacity)
> + return ERR_PTR(-ENOMEM);
> +
> + ret = alloc->curr;
> + alloc->curr += size;
> + alloc->pos += size;
> + return ret;
> +}
> +
> +static struct drm_panthor_dump_header *
> +alloc_header(struct dump_allocator *alloc, u32 type, size_t size)
> +{
> + struct drm_panthor_dump_header *hdr;
> + int header_size = sizeof(*hdr);
> +
> + hdr = alloc_bytes(alloc, header_size);
> + if (IS_ERR(hdr))
> + return hdr;
> +
> + hdr->magic = PANT_DUMP_MAGIC;
> + hdr->header_type = type;
> + hdr->header_size = header_size;
> + hdr->data_size = size;
> + return hdr;
> +}
> +
> +static int dump_bo(struct panthor_device *ptdev, u8 *dst,
> + struct drm_gem_object *obj, int offset, int size)
> +{
> + struct iosys_map map = {};
> + int ret;
> +
> + ret = drm_gem_vmap_unlocked(obj, &map);
> + if (ret)
> + return ret;
> +
> + drm_dbg(&ptdev->base, "dumping bo %p, offset %d, size %d\n", obj,
> + offset, size);
> +
> + memcpy(dst, map.vaddr + offset, size);
> + drm_gem_vunmap_unlocked(obj, &map);
> + return ret;
> +}
> +
> +static int dump_va(struct dump_va_args *dump_va_args,
> + const struct drm_gpuva *va, int type)
> +{
> + struct drm_gem_object *obj = va->gem.obj;
> + const int hdr_size =
> + sizeof(struct drm_panthor_dump_gpuva) + va->va.range;
> + struct drm_panthor_dump_gpuva *dump_va;
> + struct drm_panthor_dump_header *dump_hdr;
> + u8 *bo_data;
> +
> + dump_hdr = alloc_header(dump_va_args->alloc, type, hdr_size);
> + if (IS_ERR(dump_hdr))
> + return PTR_ERR(dump_hdr);
> +
> + dump_va = alloc_bytes(dump_va_args->alloc, sizeof(*dump_va));
> + if (IS_ERR(dump_va))
> + return PTR_ERR(dump_va);
> +
> + bo_data = alloc_bytes(dump_va_args->alloc, va->va.range);
> + if (IS_ERR(bo_data))
> + return PTR_ERR(bo_data);
> +
> + dump_va->addr = va->va.addr;
> + dump_va->range = va->va.range;
> +
> + return dump_bo(dump_va_args->ptdev, bo_data, obj, va->gem.offset,
> + va->va.range);
> +}
> +
> +static int dump_va_cb(void *priv, const struct drm_gpuva *va)
> +{
> + struct dump_va_args *dump_va_args = priv;
> + int ret;
> +
> + ret = dump_va(dump_va_args, va, DRM_PANTHOR_DUMP_HEADER_TYPE_VM);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +static int count_va_cb(void *priv, const struct drm_gpuva *va)
> +{
> + struct vm_dump_count *count = priv;
> +
> + count->vas++;
> + count->size += va->va.range;
> + return 0;
> +}
> +
> +static void count_queues(struct queue_count *count,
> + struct drm_panthor_dump_group_info *info)
> +{
> + count->queues += info->queue_count;
> +}
> +
> +static int compute_dump_size(struct vm_dump_count *va_count,
> + struct queue_count *group_and_q_cnt)
> +{
> + int size = 0;
> + int i;
> +
> + size += sizeof(struct drm_panthor_dump_header);
> + size += sizeof(struct drm_panthor_dump_version);
> +
> + size += sizeof(struct drm_panthor_dump_header);
> + size += sizeof(struct drm_panthor_gpu_info);
> +
> + size += sizeof(struct drm_panthor_dump_header);
> + size += sizeof(struct drm_panthor_csif_info);
> +
> + size += sizeof(struct drm_panthor_dump_header);
> + size += sizeof(struct drm_panthor_fw_info);
> +
> + for (i = 0; i < va_count->vas; i++) {
> + size += sizeof(struct drm_panthor_dump_header);
> + size += sizeof(struct drm_panthor_dump_gpuva);
> + }
> +
> + size += va_count->size;
> +
> + size += sizeof(struct drm_panthor_dump_header);
> + size += sizeof(struct drm_panthor_dump_group_info);
> +
> + for (i = 0; i < group_and_q_cnt->queues; i++) {
> + size += sizeof(struct drm_panthor_dump_header);
> + size += sizeof(struct drm_panthor_dump_queue_info);
> + }
> +
> + return size;
> +}
> +
> +static int dump_queue_info(struct dump_group_args *dump_group_args,
> + struct drm_panthor_dump_queue_info *info)
> +{
> + struct drm_panthor_dump_header *hdr;
> + struct drm_panthor_dump_queue_info *queue_info;
> +
> + drm_dbg(&dump_group_args->ptdev->base,
> + "dumping queue info for cs_id %d, gpuva: %llx, insert: %llx, extract: %llx\n",
> + info->cs_id, info->ringbuf_gpuva, info->ringbuf_insert,
> + info->ringbuf_extract);
> +
> + hdr = alloc_header(dump_group_args->alloc,
> + DRM_PANTHOR_DUMP_HEADER_TYPE_QUEUE_INFO,
> + sizeof(*info));
> + if (IS_ERR(hdr))
> + return PTR_ERR(hdr);
> +
> + queue_info = alloc_bytes(dump_group_args->alloc, sizeof(*queue_info));
> + if (IS_ERR(queue_info))
> + return PTR_ERR(queue_info);
> +
> + *queue_info = *info;
> + return 0;
> +}
> +
> +static int dump_group_info(struct dump_group_args *dump_group_args,
> + struct drm_panthor_dump_group_info *info)
> +{
> + struct drm_panthor_dump_header *hdr;
> + struct drm_panthor_dump_group_info *group_info;
> + int ret = 0;
> +
> + drm_dbg(&dump_group_args->ptdev->base,
> + "dumping group info for num_queues: %d, faulty bitmask: %d\n",
> + info->queue_count, info->faulty_bitmask);
> +
> + hdr = alloc_header(dump_group_args->alloc,
> + DRM_PANTHOR_DUMP_HEADER_TYPE_GROUP_INFO,
> + sizeof(*info));
> + if (IS_ERR(hdr))
> + return PTR_ERR(hdr);
> +
> + group_info = alloc_bytes(dump_group_args->alloc, sizeof(*group_info));
> + if (IS_ERR(group_info))
> + return PTR_ERR(group_info);
> +
> + *group_info = *info;
> +
> + for (int i = 0; i < info->queue_count; i++) {
> + struct drm_panthor_dump_queue_info qinfo;
> +
> + ret = panthor_sched_get_queueinfo(dump_group_args->group, i,
> + &qinfo);
> + if (ret)
> + break;
> + ret = dump_queue_info(dump_group_args, &qinfo);
> + if (ret)
> + break;
> + }
> +
> + return ret;
> +}
> +
> +int panthor_core_dump(struct panthor_core_dump_args *args)
> +{
> + u8 *mem;
> + int dump_size;
> + int ret = 0;
> + struct dump_allocator alloc = {};
> + struct vm_dump_count va_count = {};
> + struct drm_panthor_dump_header *hdr;
> + struct drm_panthor_dump_version *version;
> + struct drm_panthor_gpu_info *gpu_info;
> + struct drm_panthor_csif_info *csif_info;
> + struct drm_panthor_fw_info *fw_info;
> + struct queue_count group_and_q_cnt = {};
> + struct dump_va_args dump_va_args = {};
> + struct drm_panthor_dump_group_info group_info;
> + struct dump_group_args dump_group_args;
> +
> + panthor_vm_foreach_va(args->group_vm, count_va_cb, &va_count);
> +
> + panthor_sched_get_groupinfo(args->group, &group_info);
> +
> + count_queues(&group_and_q_cnt, &group_info);
> +
> + dump_size = compute_dump_size(&va_count, &group_and_q_cnt);
> +
> + mem = vzalloc(dump_size);
> + if (!mem)
> + return ret;
> +
> + alloc = (struct dump_allocator){
> + .start = mem,
> + .curr = mem,
> + .pos = 0,
> + .capacity = dump_size,
> + };
> +
> + hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_VERSION,
> + sizeof(struct drm_panthor_dump_version));
> + if (IS_ERR(hdr)) {
> + ret = PTR_ERR(hdr);
> + goto free_valloc;
> + }
> +
> + version = alloc_bytes(&alloc, sizeof(*version));
> + if (IS_ERR(version)) {
> + ret = PTR_ERR(version);
> + goto free_valloc;
> + }
> +
> + *version = (struct drm_panthor_dump_version){
> + .major = PANT_DUMP_MAJOR,
> + .minor = PANT_DUMP_MINOR,
> + };
> +
> + hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_GPU_INFO,
> + sizeof(args->ptdev->gpu_info));
> + if (IS_ERR(hdr)) {
> + ret = PTR_ERR(hdr);
> + goto free_valloc;
> + }
> +
> + gpu_info = alloc_bytes(&alloc, sizeof(*gpu_info));
> + if (IS_ERR(gpu_info)) {
> + ret = PTR_ERR(gpu_info);
> + goto free_valloc;
> + }
> +
> + *gpu_info = args->ptdev->gpu_info;
> +
> + hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_CSIF_INFO,
> + sizeof(args->ptdev->csif_info));
> + if (IS_ERR(hdr)) {
> + ret = PTR_ERR(hdr);
> + goto free_valloc;
> + }
> +
> + csif_info = alloc_bytes(&alloc, sizeof(*csif_info));
> + if (IS_ERR(csif_info)) {
> + ret = PTR_ERR(csif_info);
> + goto free_valloc;
> + }
> +
> + *csif_info = args->ptdev->csif_info;
> +
> + hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_FW_INFO,
> + sizeof(args->ptdev->fw_info));
> + if (IS_ERR(hdr)) {
> + ret = PTR_ERR(hdr);
> + goto free_valloc;
> + }
> +
> + fw_info = alloc_bytes(&alloc, sizeof(*fw_info));
> + if (IS_ERR(fw_info)) {
> + ret = PTR_ERR(fw_info);
> + goto free_valloc;
> + }
> +
> + *fw_info = args->ptdev->fw_info;
> +
> + dump_va_args.ptdev = args->ptdev;
> + dump_va_args.alloc = &alloc;
> + ret = panthor_vm_foreach_va(args->group_vm, dump_va_cb, &dump_va_args);
> + if (ret)
> + goto free_valloc;
> +
> + dump_group_args =
> + (struct dump_group_args){ args->ptdev, &alloc, args->group };
> + panthor_sched_get_groupinfo(args->group, &group_info);
> + dump_group_info(&dump_group_args, &group_info);
> +
> + if (alloc.pos < dump_size)
> + drm_warn(&args->ptdev->base,
> + "dump size mismatch: expected %d, got %zu\n",
> + dump_size, alloc.pos);
> +
> + dev_coredumpv(args->ptdev->base.dev, alloc.start, alloc.pos,
> + GFP_KERNEL);
> +
> + return ret;
> +
> +free_valloc:
> + vfree(mem);
> + return ret;
> +}
> diff --git a/drivers/gpu/drm/panthor/panthor_dump.h b/drivers/gpu/drm/panthor/panthor_dump.h
> new file mode 100644
> index 000000000000..2a02943a2dbd
> --- /dev/null
> +++ b/drivers/gpu/drm/panthor/panthor_dump.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0 or MIT */
> +/* SPDX-FileCopyrightText: Copyright Collabora 2024 */
> +
> +#ifndef __PANTHOR_DUMP_H__
> +#define __PANTHOR_DUMP_H__
> +
> +#include <drm/drm_gpuvm.h>
> +#include <drm/panthor_drm.h>
> +
> +#include "panthor_device.h"
> +#include "panthor_gem.h"
> +
> +struct panthor_core_dump_args {
> + struct panthor_device *ptdev;
> + struct panthor_vm *group_vm;
> + struct panthor_group *group;
> +};
> +
> +int panthor_core_dump(struct panthor_core_dump_args *args);
> +
> +#endif /* __PANTHOR_DUMP_H__ */
> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
> index 412e95fcfb92..61d61157ace0 100644
> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
> @@ -2632,6 +2632,28 @@ int panthor_vm_prepare_mapped_bos_resvs(struct drm_exec *exec, struct panthor_vm
> return drm_gpuvm_prepare_objects(&vm->base, exec, slot_count);
> }
>
> +/**
> + * panthor_vm_foreachva() - Execute a callback for each VA in a VM
> + *
> + */
> +int panthor_vm_foreach_va(struct panthor_vm *vm,
> + int (*cb)(void *priv, const struct drm_gpuva *va),
> + void *priv)
> +{
> + struct drm_gpuva *va;
> + int ret = 0;
> +
> + mutex_lock(&vm->op_lock);
> + drm_gpuvm_for_each_va(va, &vm->base) {
> + ret = cb(priv, va);
> + if (ret)
> + break;
> + }
> + mutex_unlock(&vm->op_lock);
> +
> + return ret;
> +}
> +
> /**
> * panthor_mmu_unplug() - Unplug the MMU logic
> * @ptdev: Device.
> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.h b/drivers/gpu/drm/panthor/panthor_mmu.h
> index 6788771071e3..05a5d68b23ae 100644
> --- a/drivers/gpu/drm/panthor/panthor_mmu.h
> +++ b/drivers/gpu/drm/panthor/panthor_mmu.h
> @@ -8,6 +8,7 @@
> #include <linux/dma-resv.h>
>
> struct drm_exec;
> +struct drm_gpuva;
> struct drm_sched_job;
> struct panthor_gem_object;
> struct panthor_heap_pool;
> @@ -52,6 +53,11 @@ void panthor_vm_add_job_fence_to_bos_resvs(struct panthor_vm *vm,
> struct drm_sched_job *job);
>
> struct dma_resv *panthor_vm_resv(struct panthor_vm *vm);
> +
> +int panthor_vm_foreach_va(struct panthor_vm *vm,
> + int (*cb)(void *priv, const struct drm_gpuva *va),
> + void *priv);
> +
> struct drm_gem_object *panthor_vm_root_gem(struct panthor_vm *vm);
>
> void panthor_vm_pool_destroy(struct panthor_file *pfile);
> diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
> index e0ecc8bcfaae..59c30b311ee9 100644
> --- a/drivers/gpu/drm/panthor/panthor_sched.c
> +++ b/drivers/gpu/drm/panthor/panthor_sched.c
> @@ -24,6 +24,7 @@
>
> #include "panthor_devfreq.h"
> #include "panthor_device.h"
> +#include "panthor_dump.h"
> #include "panthor_fw.h"
> #include "panthor_gem.h"
> #include "panthor_gpu.h"
> @@ -2805,6 +2806,45 @@ static void group_sync_upd_work(struct work_struct *work)
> group_put(group);
> }
>
> +/**
> + * panthor_sched_get_groupinfo() - Build a group info structure for the group
> + *
> + * @group: the group to build a group info structure for
> + * @info: the group info structure to fill
> + */
> +void panthor_sched_get_groupinfo(struct panthor_group *group,
> + struct drm_panthor_dump_group_info *info)
> +{
> + info->queue_count = group->queue_count;
> + info->faulty_bitmask = group->fatal_queues;
> +}
> +
> +/** panthor_sched_get_queueinfo() - Build a queue info structure for a queue
> + * given its group and its cs_id
> + *
> + * @group: the group the queue belongs to
> + * @cs_id: the command stream ID of the queue
> + * @info: the queue info structure to fill
> + */
> +int panthor_sched_get_queueinfo(struct panthor_group *group, u32 cs_id,
> + struct drm_panthor_dump_queue_info *info)
> +{
> + struct panthor_queue *queue;
> +
> + if (cs_id >= group->queue_count)
> + return -EINVAL;
> +
> + queue = group->queues[cs_id];
> +
> + info->cs_id = cs_id;
> + info->ringbuf_insert = queue->iface.input->insert;
> + info->ringbuf_extract = queue->iface.output->extract;
> + info->ringbuf_gpuva = panthor_kernel_bo_gpuva(queue->ringbuf);
> + info->ringbuf_size = panthor_kernel_bo_size(queue->ringbuf);
> +
> + return 0;
> +}
> +
> static struct dma_fence *
> queue_run_job(struct drm_sched_job *sched_job)
> {
> @@ -2946,7 +2986,7 @@ queue_timedout_job(struct drm_sched_job *sched_job)
> struct panthor_device *ptdev = group->ptdev;
> struct panthor_scheduler *sched = ptdev->scheduler;
> struct panthor_queue *queue = group->queues[job->queue_idx];
> -
> + struct panthor_core_dump_args core_dump_args;
> drm_warn(&ptdev->base, "job timeout\n");
>
> drm_WARN_ON(&ptdev->base, atomic_read(&sched->reset.in_progress));
> @@ -2955,6 +2995,15 @@ queue_timedout_job(struct drm_sched_job *sched_job)
>
> mutex_lock(&sched->lock);
> group->timedout = true;
> +
> + core_dump_args = (struct panthor_core_dump_args) {
> + .ptdev = ptdev,
> + .group_vm = job->group->vm,
> + .group = job->group,
> + };
> +
> + panthor_core_dump(&core_dump_args);
> +
> if (group->csg_id >= 0) {
> sched_queue_delayed_work(ptdev->scheduler, tick, 0);
> } else {
> diff --git a/drivers/gpu/drm/panthor/panthor_sched.h b/drivers/gpu/drm/panthor/panthor_sched.h
> index 3a30d2328b30..9a5b53498dcc 100644
> --- a/drivers/gpu/drm/panthor/panthor_sched.h
> +++ b/drivers/gpu/drm/panthor/panthor_sched.h
> @@ -17,6 +17,9 @@ struct panthor_device;
> struct panthor_file;
> struct panthor_group_pool;
> struct panthor_job;
> +struct panthor_group;
> +struct drm_panthor_dump_group_info;
> +struct drm_panthor_dump_queue_info;
>
> int panthor_group_create(struct panthor_file *pfile,
> const struct drm_panthor_group_create *group_args,
> @@ -41,6 +44,13 @@ int panthor_sched_init(struct panthor_device *ptdev);
> void panthor_sched_unplug(struct panthor_device *ptdev);
> void panthor_sched_pre_reset(struct panthor_device *ptdev);
> void panthor_sched_post_reset(struct panthor_device *ptdev, bool reset_failed);
> +
> +void panthor_sched_get_groupinfo(struct panthor_group *group,
> + struct drm_panthor_dump_group_info *info);
> +
> +int panthor_sched_get_queueinfo(struct panthor_group *group, u32 cs_id,
> + struct drm_panthor_dump_queue_info *info);
> +
> void panthor_sched_suspend(struct panthor_device *ptdev);
> void panthor_sched_resume(struct panthor_device *ptdev);
>
> diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h
> index e235cf452460..82ec0f20c49e 100644
> --- a/include/uapi/drm/panthor_drm.h
> +++ b/include/uapi/drm/panthor_drm.h
> @@ -969,6 +969,130 @@ struct drm_panthor_tiler_heap_destroy {
> __u32 pad;
> };
>
> +/**
> + * enum drm_panthor_dump_header_type - Identifies the type of data that follows
> + * in a panthor core dump.
> + */
> +enum drm_panthor_dump_header_type {
> + DRM_PANTHOR_DUMP_HEADER_TYPE_VERSION = 0,
> + /**
> + * @DRM_PANTHOR_DUMP_HEADER_TYPE_GPU_INFO: Gpu information.
> + */
> + DRM_PANTHOR_DUMP_HEADER_TYPE_GPU_INFO = 1,
> + /**
> + * @DRM_PANTHOR_DUMP_HEADER_TYPE_CSIF_INFO: Command stream interface information.
> + */
> + DRM_PANTHOR_DUMP_HEADER_TYPE_CSIF_INFO = 2,
> + /**
> + * @DRM_PANTHOR_DUMP_HEADER_TYPE_FW_INFO: Information about the firmware.
> + */
> + DRM_PANTHOR_DUMP_HEADER_TYPE_FW_INFO = 3,
> + /**
> + * @DRM_PANTHOR_DUMP_HEADER_TYPE_VM: A dump of the VM for the context.
> + */
> + DRM_PANTHOR_DUMP_HEADER_TYPE_VM = 4,
> + /**
> + * @DRM_PANTHOR_DUMP_HEADER_TYPE_GROUP_INFO: Describes a group. A dump can
> + * contain either the faulty group, or all groups for the DRM FD.
> + */
> + DRM_PANTHOR_DUMP_HEADER_TYPE_GROUP_INFO = 5,
> + /**
> + * @DRM_PANTHOR_DUMP_HEADER_TYPE_QUEUE_INFO: Describes a faulty queue. This
> + * will immediately follow a group info.
> + */
> + DRM_PANTHOR_DUMP_HEADER_TYPE_QUEUE_INFO = 6,
> +};
> +
> +/**
> + * struct drm_panthor_dump_header - A header that describes a section of a panthor core dump.
> + */
> +struct drm_panthor_dump_header {
> + /** @magic: Always set to PANT (0x544e4150). */
> + __u32 magic;
> +
> + /** @header_type: Identifies the type of data in the following section of the
> + * core dump file
> + */
> + enum drm_panthor_dump_header_type header_type;
> +
> + /** @header_size: The size of the header.
> + *
> + * This is for backward-compatibility purposes in case this structure is
> + * augmented in the future. It allows userspace to skip over the header and
> + * access the actual data it describes.
> + */
> + __u32 header_size;
> +
> + /** @data_size: The size of the following section */
> + __u32 data_size;
> +};
> +
> +/**
> + * struct drm_panthor_dump_version - Version information for a Panthor GPU dump.
> + *
> + * This structure is used to hold version information when performing a dump of
> + * the state of a Panthor GPU.
> + */
> +struct drm_panthor_dump_version {
> + /** @major: Versioning information for backwards compatibility */
> + __u32 major;
> + /** @minor: Versioning information for backwards compatibility */
> + __u32 minor;
> +};
> +
> +/**
> + * struct drm_panthor_dump_group_info - Group information for a Panthor GPU
> + * dump.
> + *
> + * This structure is used to hold information about a group when performing a
> + * dump of the state of a Panthor GPU.
> + */
> +struct drm_panthor_dump_group_info {
> + /** @queue_count: The number of queues in the group. */
> + __u32 queue_count;
> + /** @faulty_queues: A bitmask denoting the faulty queues */
> + __u32 faulty_bitmask;
> +};
> +
> +#define DRM_PANTHOR_DUMP_QUEUE_INFO_FLAGS_FAULTY (1 << 0)
> +
> +/**
> + * struct drm_panthor_dump_queue_info - Queue information for a Panthor GPU
> + * dump.
> + *
> + * This structure is used to hold information about a queue when performing a
> + * dump of the state of a Panthor GPU.
> + */
> +struct drm_panthor_dump_queue_info {
> + /** See DRM_PANTHOR_DUMP_QUEUE_INFO_FLAGS_XXX */
> + u32 flags;
> + /** @cs_id: The ID of the command stream. */
> + __s32 cs_id;
> + /** @faulty: Whether this queue has faulted */
> + /** @ringbuf_gpuva: The GPU virtual address of the ring buffer. */
> + __u64 ringbuf_gpuva;
> + /** @ringbuf_insert: The insert point (i.e.: offset) in the ring buffer. This
> + * is where a instruction would be inserted next by the CPU.
> + */
> + __u64 ringbuf_insert;
> + /** @ringbuf_extract: The extract point (i.e.: offset) in the ring buffer.
> + * This is where the GPU would read the next instruction.
> + */
> + __u64 ringbuf_extract;
> + /** @ringbuf_size: The size of the ring buffer */
> + __u64 ringbuf_size;
> +};
> +
> +/**
> + * struct drm_panthor_dump_gpuva - Describes a GPU VA range in the dump.
> + */
> +struct drm_panthor_dump_gpuva {
> + /** @addr: The start address for the mapping */
> + __u64 addr;
> + /** @range: The range covered by the VA mapping */
> + __u64 range;
> +};
> +
> #if defined(__cplusplus)
> }
> #endif
> --
> 2.45.2