From nobody Tue Feb 10 19:48:45 2026 Received: from mail-ed1-f46.google.com (mail-ed1-f46.google.com [209.85.208.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9BB6638A728 for ; Tue, 13 Jan 2026 17:44:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768326296; cv=none; b=bag5FvISVIPxFCH5sP8EUwmN7naNbBF3VZnFqTlVJvlcB0+dgnlhdgQw/A9YhkTSg6Bd05yGF9LCRrs9TOJsIpqOApLRZlfISSwlA+sobD63YtDt+Wf34w5hWJPmOBWHran31SZdQcYmM15HjMilJqNmqSMMR65gUlQJWWLtuSc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768326296; c=relaxed/simple; bh=0g5pzZX8iq/6GrnWszbWTiqB1hDUiyTHSZtgWFCmxmo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cywB/Npxgg85CWXDASSjfjCuvK/gKkWAV02bwARGGowokYqEY2qgReaFEsCdKB51rcddY6H1bbAaG0xL4X4FDSGINuyVb+LH6DGxA3OuLGTz61u+LWzA+imZhHLmnOt65N+7H+7HR3LvTs8oUgaADNNIPnsKhtgXHu9Zm9U8jlw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tomeuvizoso.net; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.208.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tomeuvizoso.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ed1-f46.google.com with SMTP id 4fb4d7f45d1cf-64b4b35c812so12796832a12.0 for ; Tue, 13 Jan 2026 09:44:54 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768326293; x=1768931093; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=v2l8wIBjsApl5lsjMAOqlkMIbLPfjDWiLseIy2qbcjU=; b=XS1jw4LDJhWH8xoiVynOeQ7V3Dan2RlKmYZcA++lAi48UguCa5u+fpBBZPxxWewhXS wSviTJHMOcK39VRZPfcSrhZW55pFLAZ00Bui99vaUpw9jo257QPq/REWgI6bsFzkWiNy Xxf80CwuPajIDcHKikayEX8fnN4y/ExHbcFHLopb/wukgdmJLK5MZkz5dQwwnyCCt2IM OJfThHH2xNCbwt9oLT+/KJWwqT/4mRidSc3fwLTj6/z+vUFeUuyojc+f7I3WU0YUwA96 cp51ngI4NRPvSQVN2gekdormENe/GtrRE+zF0a5JA2eCAciat+komLIxcVM24YRLDcmx vcrg== X-Forwarded-Encrypted: i=1; AJvYcCWOy011NjXhUpfJs5UP6tn6gTNw6f3mtwoCGiwmJ7cUhHcME/ANbWm3gsGVVsBPOqOI/KvTUYDC7qPfbZA=@vger.kernel.org X-Gm-Message-State: AOJu0YyfKQxO0W6FQfHcFZUckk62839FWfQnhE9Uor3JnMyJmlKr+hBY W5qq8fNNGl9YrK/3GE1olt8tYkmaeuyGJyBpu3o9j7t0iwMf/q90mYQz X-Gm-Gg: AY/fxX5h6opL6PZIJPhSYphIabHrtaWVejmRoJc+KkoBbGxzuUDRA8f6VBy/E63FYJ1 VhcfZFBSns2rCeYaxGfi3LvNYv7vTKVoO+ST/af9PRJ0BKm3JlXC1/DiLc6plUweKsl7vYxkviF 8YnRGGDCWM6em7oYp1pECvPhgI9XcsraUCO3tWWmKFI8+YdN542Cg9J7Mq/94vXO+0nYmMm/tyD eRLOofzQpv3RC7hUDwhD9ao6WY/f3BimSe+1BE6c8HmiEXKvmbDLPGGthNu4UBA1PRn+ivoOfZE QltcMfuMGj7KwwLcDfAYIZMNEaolv/R7d/j9UkQC2tSfCxL6UP1awmVT5yYy9Bdk6aD3qLqfBVV HXu6/nZmt+Z/rwd4YTsmOiqQV39YHAZmJ/nXwtXOjhgc1KqztTA+aJLzvAW8AMM4W0M8ctkG9sl XtnU4lZBZzSNozVCK2ah0ykf9DB4UZ1v5epczcISvW2ZEdHg== X-Google-Smtp-Source: AGHT+IGYYREEN/5lBbERJSEIoYk6+xX8TKQHB6V6QK9t02Hm3hex4r4o0KRxPxU4VDxzdmDeNKmVmQ== X-Received: by 2002:a05:6402:1e92:b0:653:9cd7:2004 with SMTP id 4fb4d7f45d1cf-6539cd72323mr1132657a12.28.1768326292719; Tue, 13 Jan 2026 09:44:52 -0800 (PST) Received: from [10.42.0.1] (cst-prg-36-231.cust.vodafone.cz. [46.135.36.231]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6507be655aesm20873259a12.17.2026.01.13.09.44.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Jan 2026 09:44:52 -0800 (PST) From: Tomeu Vizoso Date: Tue, 13 Jan 2026 18:44:37 +0100 Subject: [PATCH 3/5] accel/thames: Add IOCTLs for BO creation and mapping Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260113-thames-v1-3-99390026937c@tomeuvizoso.net> References: <20260113-thames-v1-0-99390026937c@tomeuvizoso.net> In-Reply-To: <20260113-thames-v1-0-99390026937c@tomeuvizoso.net> To: Nishanth Menon , "Andrew F. Davis" , Randolph Sapp , Jonathan Humphreys , Andrei Aldea , Chirag Shilwant , Vignesh Raghavendra , Tero Kristo , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Oded Gabbay , Jonathan Corbet , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= Cc: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org, linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org, Tomeu Vizoso X-Mailer: b4 0.14.2 Uses the SHMEM DRM helpers, mapping on creation to the device as all created buffers are expected to be accessed by the DSPs. We map to all DSPs because we cannot know upfront what DSP cores will run a given job. Buffers are mapped for the device by the DSPs themselves, as each contains a MMU. Buffers belong to a context, which is used by the DSP to switch to the page table that mapped the buffers for the user of the job to execute. Signed-off-by: Tomeu Vizoso --- drivers/accel/thames/Makefile | 1 + drivers/accel/thames/thames_drv.c | 5 +- drivers/accel/thames/thames_gem.c | 355 ++++++++++++++++++++++++++++++++= ++++ drivers/accel/thames/thames_gem.h | 41 +++++ drivers/accel/thames/thames_rpmsg.c | 69 +++++++ 5 files changed, 470 insertions(+), 1 deletion(-) diff --git a/drivers/accel/thames/Makefile b/drivers/accel/thames/Makefile index 7ccd8204f0f5ea800f30e84b319f355be948109d..0051e319f2e4966de72bc342d5b= 6e40b2890c006 100644 --- a/drivers/accel/thames/Makefile +++ b/drivers/accel/thames/Makefile @@ -6,4 +6,5 @@ thames-y :=3D \ thames_core.o \ thames_device.o \ thames_drv.o \ + thames_gem.o \ thames_rpmsg.o diff --git a/drivers/accel/thames/thames_drv.c b/drivers/accel/thames/thame= s_drv.c index a288e6ef05d7b1a21741ac0ca9cc8981f33969e4..29a80b9747ae84778b09f5dbd5b= 8d6d596f1947a 100644 --- a/drivers/accel/thames/thames_drv.c +++ b/drivers/accel/thames/thames_drv.c @@ -13,6 +13,7 @@ =20 #include "thames_drv.h" #include "thames_core.h" +#include "thames_gem.h" #include "thames_ipc.h" =20 static struct platform_device *drm_dev; @@ -54,7 +55,8 @@ static void thames_postclose(struct drm_device *dev, stru= ct drm_file *file) =20 static const struct drm_ioctl_desc thames_drm_driver_ioctls[] =3D { #define THAMES_IOCTL(n, func) DRM_IOCTL_DEF_DRV(THAMES_##n, thames_ioctl_#= #func, 0) - + THAMES_IOCTL(BO_CREATE, bo_create), + THAMES_IOCTL(BO_MMAP_OFFSET, bo_mmap_offset), }; =20 DEFINE_DRM_ACCEL_FOPS(thames_accel_driver_fops); @@ -63,6 +65,7 @@ static const struct drm_driver thames_drm_driver =3D { .driver_features =3D DRIVER_COMPUTE_ACCEL | DRIVER_GEM, .open =3D thames_open, .postclose =3D thames_postclose, + .gem_create_object =3D thames_gem_create_object, .ioctls =3D thames_drm_driver_ioctls, .num_ioctls =3D ARRAY_SIZE(thames_drm_driver_ioctls), .fops =3D &thames_accel_driver_fops, diff --git a/drivers/accel/thames/thames_gem.c b/drivers/accel/thames/thame= s_gem.c new file mode 100644 index 0000000000000000000000000000000000000000..a153e73a15253e0f955d74020b4= 765a1fa833fc4 --- /dev/null +++ b/drivers/accel/thames/thames_gem.c @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright 2026 Texas Instruments Incorporated - https://www.ti.com/ */ + +#include "drm/drm_gem_shmem_helper.h" +#include +#include +#include +#include +#include +#include +#include + +#include "thames_gem.h" +#include "thames_device.h" +#include "thames_drv.h" +#include "thames_rpmsg.h" + +#define THAMES_BO_FLAGS DRM_THAMES_BO_NO_MMAP + +/* + * DSP MMU permission flags for buffer object mappings. + * These control read/write/execute permissions in the DSP's address space. + */ +#define THAMES_BO_PERM_READ (1 << 0) +#define THAMES_BO_PERM_WRITE (1 << 1) +#define THAMES_BO_PERM_EXEC (1 << 2) +#define THAMES_BO_PERM_RWX (THAMES_BO_PERM_READ | THAMES_BO_PERM_WRITE | T= HAMES_BO_PERM_EXEC) + +static u64 thames_alloc_vaddr(struct thames_device *tdev, struct thames_ge= m_object *bo, size_t size) +{ + int ret; + + size =3D ALIGN(size, SZ_1M); + + mutex_lock(&tdev->mm_lock); + ret =3D drm_mm_insert_node(&tdev->mm, &bo->mm, size); + mutex_unlock(&tdev->mm_lock); + + if (ret) + return 0; + + return bo->mm.start; +} + +static void thames_free_vaddr(struct thames_device *tdev, struct thames_ge= m_object *bo) +{ + if (!drm_mm_node_allocated(&bo->mm)) + return; + + mutex_lock(&tdev->mm_lock); + drm_mm_remove_node(&bo->mm); + mutex_unlock(&tdev->mm_lock); +} + +static int thames_context_destroy_on_core(struct thames_file_priv *priv, s= truct thames_core *core) +{ + struct thames_device *tdev =3D priv->tdev; + int ret; + + ret =3D thames_rpmsg_send_destroy_context(core, priv->context_id); + if (ret) + dev_warn(tdev->ddev.dev, "Failed to destroy context on core %d: %d", cor= e->index, + ret); + + return ret; +} + +static int thames_context_create_on_core(struct thames_file_priv *priv, st= ruct thames_core *core) +{ + struct thames_device *tdev =3D priv->tdev; + int ret; + + ret =3D thames_rpmsg_send_create_context(core, priv->context_id); + if (ret) + dev_warn(tdev->ddev.dev, "Failed to create context on core %d: %d", core= ->index, + ret); + + return ret; +} + +int thames_context_create(struct thames_file_priv *priv) +{ + struct thames_device *tdev =3D priv->tdev; + int i, ret; + + ret =3D ida_alloc_min(&tdev->ctx_ida, 1, GFP_KERNEL); + if (ret < 0) + return ret; + + priv->context_id =3D ret; + priv->context_valid =3D false; + + if (!tdev->num_cores) { + dev_err(tdev->ddev.dev, "No cores available\n"); + ret =3D -ENODEV; + goto err_free_id; + } + + for (i =3D 0; i < tdev->num_cores; i++) { + ret =3D thames_context_create_on_core(priv, &tdev->cores[i]); + if (ret) { + dev_err(tdev->ddev.dev, "Failed to create context on core %d: %d\n", i, + ret); + goto err_destroy_contexts; + } + } + + priv->context_valid =3D true; + return 0; + +err_destroy_contexts: + for (i =3D i - 1; i >=3D 0; i--) + thames_context_destroy_on_core(priv, &tdev->cores[i]); +err_free_id: + ida_free(&tdev->ctx_ida, priv->context_id); + return ret; +} + +void thames_context_destroy(struct thames_file_priv *priv) +{ + struct thames_device *tdev =3D priv->tdev; + int i; + + if (!priv->context_valid) + return; + + for (i =3D 0; i < tdev->num_cores; i++) + thames_context_destroy_on_core(priv, &tdev->cores[i]); + + ida_free(&tdev->ctx_ida, priv->context_id); + priv->context_valid =3D false; +} + +static int thames_bo_map_to_core(struct thames_gem_object *bo, struct tham= es_file_priv *file_priv, + struct thames_core *core, u64 vaddr, u64 paddr, u64 size, + u32 flags) +{ + struct thames_device *tdev =3D file_priv->tdev; + int ret; + + ret =3D thames_rpmsg_send_map_bo(core, file_priv->context_id, bo->id, vad= dr, paddr, size); + if (ret) + dev_warn(tdev->ddev.dev, "Failed to map buffer on core %d: %d", core->in= dex, ret); + + return ret; +} + +static int thames_bo_map_to_device(struct thames_gem_object *bo, struct th= ames_file_priv *file_priv) +{ + struct thames_device *tdev =3D file_priv->tdev; + struct sg_table *sgt; + dma_addr_t dma_addr; + int i, ret; + + if (bo->iova) + return 0; + + if (!file_priv->context_valid) + return -EINVAL; + + if (!tdev->num_cores) + return -ENODEV; + + sgt =3D drm_gem_shmem_get_pages_sgt(&bo->base); + if (IS_ERR(sgt)) + return PTR_ERR(sgt); + + dma_addr =3D sg_dma_address(sgt->sgl); + if (!dma_addr) { + ret =3D -EINVAL; + goto err_put_pages; + } + + bo->iova =3D thames_alloc_vaddr(tdev, bo, bo->base.base.size); + if (!bo->iova) { + ret =3D -ENOMEM; + goto err_put_pages; + } + + bo->context_id =3D file_priv->context_id; + + for (i =3D 0; i < tdev->num_cores; i++) { + ret =3D thames_bo_map_to_core(bo, file_priv, &tdev->cores[i], bo->iova, = dma_addr, + bo->base.base.size, THAMES_BO_PERM_RWX); + if (ret) { + while (--i >=3D 0) + thames_rpmsg_send_unmap_bo(&tdev->cores[i], bo->context_id, bo->id); + goto err_free_vaddr; + } + } + + return 0; + +err_free_vaddr: + thames_free_vaddr(tdev, bo); + bo->iova =3D 0; +err_put_pages: + dma_resv_lock(bo->base.base.resv, NULL); + drm_gem_shmem_put_pages_locked(&bo->base); + dma_resv_unlock(bo->base.base.resv); + return ret; +} + +static void thames_bo_unmap_from_device(struct thames_gem_object *bo, stru= ct thames_device *tdev) +{ + int i, ret, failed_unmaps =3D 0; + + if (!bo->iova) + return; + + for (i =3D 0; i < tdev->num_cores; i++) { + ret =3D thames_rpmsg_send_unmap_bo(&tdev->cores[i], bo->context_id, bo->= id); + if (ret) { + dev_err(tdev->ddev.dev, "Failed to unmap BO %u from core %d: %d\n", bo-= >id, + i, ret); + failed_unmaps++; + } + } + + if (failed_unmaps) + drm_WARN(&tdev->ddev, failed_unmaps > 0, + "BO %u: %d core(s) failed unmap, potential DSP-side leak\n", bo->id, + failed_unmaps); + + thames_free_vaddr(tdev, bo); + bo->iova =3D 0; + + dma_resv_lock(bo->base.base.resv, NULL); + drm_gem_shmem_put_pages_locked(&bo->base); + dma_resv_unlock(bo->base.base.resv); +} + +static void thames_gem_bo_free(struct drm_gem_object *obj) +{ + struct thames_gem_object *bo =3D to_thames_bo(obj); + struct thames_device *tdev =3D to_thames_device(obj->dev); + + drm_WARN_ON(obj->dev, refcount_read(&bo->base.pages_use_count) > 1); + + if (bo->iova) + thames_bo_unmap_from_device(bo, tdev); + + ida_free(&tdev->bo_ida, bo->id); + + drm_gem_free_mmap_offset(&bo->base.base); + drm_gem_shmem_free(&bo->base); +} + +static const struct drm_gem_object_funcs thames_gem_funcs =3D { + .free =3D thames_gem_bo_free, + .print_info =3D drm_gem_shmem_object_print_info, + .pin =3D drm_gem_shmem_object_pin, + .unpin =3D drm_gem_shmem_object_unpin, + .get_sg_table =3D drm_gem_shmem_object_get_sg_table, + .vmap =3D drm_gem_shmem_object_vmap, + .vunmap =3D drm_gem_shmem_object_vunmap, + .mmap =3D drm_gem_shmem_object_mmap, + .vm_ops =3D &drm_gem_shmem_vm_ops, +}; + +struct drm_gem_object *thames_gem_create_object(struct drm_device *dev, si= ze_t size) +{ + struct thames_device *tdev =3D to_thames_device(dev); + struct thames_gem_object *obj; + int bo_id; + + obj =3D kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) + return ERR_PTR(-ENOMEM); + + obj->base.base.funcs =3D &thames_gem_funcs; + + bo_id =3D ida_alloc_min(&tdev->bo_ida, 1, GFP_KERNEL); + if (bo_id < 0) { + kfree(obj); + return ERR_PTR(bo_id); + } + obj->id =3D bo_id; + + return &obj->base.base; +} + +int thames_ioctl_bo_create(struct drm_device *ddev, void *data, struct drm= _file *file) +{ + struct thames_file_priv *file_priv =3D file->driver_priv; + struct drm_thames_bo_create *args =3D data; + struct drm_gem_shmem_object *mem; + struct thames_gem_object *bo; + int cookie, ret; + + if (!drm_dev_enter(ddev, &cookie)) + return -ENODEV; + + if (args->handle || args->iova) { + ret =3D -EINVAL; + goto err_exit; + } + + if (!args->size || (args->flags & ~THAMES_BO_FLAGS)) { + ret =3D -EINVAL; + goto err_exit; + } + + mem =3D drm_gem_shmem_create(ddev, args->size); + if (IS_ERR(mem)) + return PTR_ERR(mem); + + bo =3D to_thames_bo(&mem->base); + + ret =3D drm_gem_handle_create(file, &mem->base, &args->handle); + drm_gem_object_put(&mem->base); + if (ret) { + dev_err(ddev->dev, "Failed to create gem handle: %d", ret); + goto err_free; + } + + ret =3D thames_bo_map_to_device(bo, file_priv); + if (ret) { + dev_err(ddev->dev, "Failed to map buffer to DSP on creation: %d", ret); + goto err_free; + } + + args->size =3D bo->base.base.size; + args->iova =3D bo->iova; + + drm_dev_exit(cookie); + + return 0; + +err_free: + drm_gem_shmem_object_free(&mem->base); + +err_exit: + drm_dev_exit(cookie); + + return ret; +} + +int thames_ioctl_bo_mmap_offset(struct drm_device *ddev, void *data, struc= t drm_file *file) +{ + struct drm_thames_bo_mmap_offset *args =3D data; + struct drm_gem_object *obj; + + if (args->pad) + return -EINVAL; + + obj =3D drm_gem_object_lookup(file, args->handle); + if (!obj) + return -ENOENT; + + args->offset =3D drm_vma_node_offset_addr(&obj->vma_node); + drm_gem_object_put(obj); + + return 0; +} diff --git a/drivers/accel/thames/thames_gem.h b/drivers/accel/thames/thame= s_gem.h new file mode 100644 index 0000000000000000000000000000000000000000..785843c40a89a9e84ab634aad77= e9ec46111693e --- /dev/null +++ b/drivers/accel/thames/thames_gem.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright 2026 Texas Instruments Incorporated - https://www.ti.com/ */ + +#ifndef __THAMES_GEM_H__ +#define __THAMES_GEM_H__ + +#include +#include + +struct thames_device; + +struct thames_gem_object { + struct drm_gem_shmem_object base; + + struct thames_file_priv *driver_priv; + + struct drm_mm_node mm; + + u32 id; + u32 context_id; + u64 iova; + size_t size; + size_t offset; +}; + +struct drm_gem_object *thames_gem_create_object(struct drm_device *dev, si= ze_t size); + +int thames_ioctl_bo_create(struct drm_device *ddev, void *data, struct drm= _file *file); + +int thames_ioctl_bo_mmap_offset(struct drm_device *ddev, void *data, struc= t drm_file *file); + +int thames_context_create(struct thames_file_priv *priv); + +void thames_context_destroy(struct thames_file_priv *priv); + +static inline struct thames_gem_object *to_thames_bo(struct drm_gem_object= *obj) +{ + return container_of(to_drm_gem_shmem_obj(obj), struct thames_gem_object, = base); +} + +#endif diff --git a/drivers/accel/thames/thames_rpmsg.c b/drivers/accel/thames/tha= mes_rpmsg.c index ebc34f49353e5e7959734da8e8a935573c130e79..a25465295a177877c5ca2b3c93f= 52d8288863797 100644 --- a/drivers/accel/thames/thames_rpmsg.c +++ b/drivers/accel/thames/thames_rpmsg.c @@ -63,6 +63,14 @@ static int thames_rpmsg_callback(struct rpmsg_device *rp= dev, void *data, int len break; } =20 + case THAMES_MSG_CONTEXT_OP_RESPONSE: + ida_free(&core->tdev->ipc_seq_ida, hdr->seq); + break; + + case THAMES_MSG_BO_OP_RESPONSE: + ida_free(&core->tdev->ipc_seq_ida, hdr->seq); + break; + default: dev_warn(&rpdev->dev, "Unknown message type: %u\n", hdr->type); break; @@ -122,6 +130,67 @@ int thames_rpmsg_send_ping(struct thames_core *core, u= 32 ping_data, u32 *sequenc return thames_rpmsg_send_raw(core, &ping_msg, sizeof(ping_msg)); } =20 +int thames_rpmsg_send_create_context(struct thames_core *core, u32 context= _id) +{ + struct thames_msg_context_op msg =3D {}; + + msg.hdr.type =3D THAMES_MSG_CONTEXT_OP; + msg.hdr.seq =3D ida_alloc(&core->tdev->ipc_seq_ida, GFP_KERNEL); + msg.hdr.len =3D sizeof(msg); + msg.op =3D THAMES_CONTEXT_CREATE; + msg.context_id =3D context_id; + + return thames_rpmsg_send_raw(core, &msg, sizeof(msg)); +} + +int thames_rpmsg_send_destroy_context(struct thames_core *core, u32 contex= t_id) +{ + struct thames_msg_context_op msg =3D {}; + + msg.hdr.type =3D THAMES_MSG_CONTEXT_OP; + msg.hdr.seq =3D ida_alloc(&core->tdev->ipc_seq_ida, GFP_KERNEL); + msg.hdr.len =3D sizeof(msg); + msg.op =3D THAMES_CONTEXT_DESTROY; + msg.context_id =3D context_id; + + return thames_rpmsg_send_raw(core, &msg, sizeof(msg)); +} + +int thames_rpmsg_send_map_bo(struct thames_core *core, u32 context_id, u32= bo_id, u64 vaddr, + u64 paddr, u64 size) +{ + struct thames_msg_bo_op msg =3D {}; + + msg.hdr.type =3D THAMES_MSG_BO_OP; + msg.hdr.seq =3D ida_alloc(&core->tdev->ipc_seq_ida, GFP_KERNEL); + msg.hdr.len =3D sizeof(msg); + msg.op =3D THAMES_BO_MAP; + msg.context_id =3D context_id; + msg.bo_id =3D bo_id; + msg.vaddr =3D vaddr; + msg.paddr =3D paddr; + msg.size =3D size; + + return thames_rpmsg_send_raw(core, &msg, sizeof(msg)); +} + +int thames_rpmsg_send_unmap_bo(struct thames_core *core, u32 context_id, u= 32 bo_id) +{ + struct thames_msg_bo_op msg =3D {}; + + msg.hdr.type =3D THAMES_MSG_BO_OP; + msg.hdr.seq =3D ida_alloc(&core->tdev->ipc_seq_ida, GFP_KERNEL); + msg.hdr.len =3D sizeof(msg); + msg.op =3D THAMES_BO_UNMAP; + msg.context_id =3D context_id; + msg.bo_id =3D bo_id; + msg.vaddr =3D 0; + msg.paddr =3D 0; + msg.size =3D 0; + + return thames_rpmsg_send_raw(core, &msg, sizeof(msg)); +} + int thames_rpmsg_ping_test(struct thames_core *core) { const u32 test_data =3D THAMES_PING_TEST_PATTERN; --=20 2.52.0