/* * Copyright 2022 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. *
*/
/* * DOC: AMDGPU TA debugfs interfaces * * Three debugfs interfaces can be opened by a program to * load/invoke/unload TA, * * - /sys/kernel/debug/dri/<N>/ta_if/ta_load * - /sys/kernel/debug/dri/<N>/ta_if/ta_invoke * - /sys/kernel/debug/dri/<N>/ta_if/ta_unload * * How to use the interfaces in a program? * * A program needs to provide transmit buffer to the interfaces * and will receive buffer from the interfaces below, * * - For TA load debugfs interface: * Transmit buffer: * - TA type (4bytes) * - TA bin length (4bytes) * - TA bin * Receive buffer: * - TA ID (4bytes) * * - For TA invoke debugfs interface: * Transmit buffer: * - TA type (4bytes) * - TA ID (4bytes) * - TA CMD ID (4bytes) * - TA shard buf length * (4bytes, value not beyond TA shared memory size) * - TA shared buf * Receive buffer: * - TA shared buf * * - For TA unload debugfs interface: * Transmit buffer: * - TA type (4bytes) * - TA ID (4bytes)
*/
ret = copy_from_user((void *)&ta_type, &buf[copy_pos], sizeof(uint32_t)); if (ret || (!is_ta_type_valid(ta_type))) return -EFAULT;
copy_pos += sizeof(uint32_t);
ret = copy_from_user((void *)&ta_bin_len, &buf[copy_pos], sizeof(uint32_t)); if (ret) return -EFAULT;
if (ta_bin_len > PSP_1_MEG) return -EINVAL;
copy_pos += sizeof(uint32_t);
ta_bin = kzalloc(ta_bin_len, GFP_KERNEL); if (!ta_bin) return -ENOMEM; if (copy_from_user((void *)ta_bin, &buf[copy_pos], ta_bin_len)) {
ret = -EFAULT; goto err_free_bin;
}
/* Set TA context and functions */
set_ta_context_funcs(psp, ta_type, &context);
if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_terminate) {
dev_err(adev->dev, "Unsupported function to terminate TA\n");
ret = -EOPNOTSUPP; goto err_free_bin;
}
/* * Allocate TA shared buf in case shared buf was freed * due to loading TA failed before.
*/ if (!context->mem_context.shared_buf) {
ret = psp_ta_init_shared_buf(psp, &context->mem_context); if (ret) {
ret = -ENOMEM; goto err_free_bin;
}
}
ret = psp_fn_ta_terminate(psp); if (ret || context->resp_status) {
dev_err(adev->dev, "Failed to unload embedded TA (%d) and status (0x%X)\n",
ret, context->resp_status); if (!ret)
ret = -EINVAL; goto err_free_ta_shared_buf;
}
/* Prepare TA context for TA initialization */
context->ta_type = ta_type;
context->bin_desc.fw_version = get_bin_version(ta_bin);
context->bin_desc.size_bytes = ta_bin_len;
context->bin_desc.start_addr = ta_bin;
if (!psp->ta_funcs->fn_ta_initialize) {
dev_err(adev->dev, "Unsupported function to initialize TA\n");
ret = -EOPNOTSUPP; goto err_free_ta_shared_buf;
}
ret = psp_fn_ta_initialize(psp); if (ret || context->resp_status) {
dev_err(adev->dev, "Failed to load TA via debugfs (%d) and status (0x%X)\n",
ret, context->resp_status); if (!ret)
ret = -EINVAL; goto err_free_ta_shared_buf;
}
if (copy_to_user((char *)buf, (void *)&context->session_id, sizeof(uint32_t)))
ret = -EFAULT;
err_free_ta_shared_buf: /* Only free TA shared buf when returns error code */ if (ret && context->mem_context.shared_buf)
psp_ta_free_shared_buf(&context->mem_context);
err_free_bin:
kfree(ta_bin);
if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_terminate) {
dev_err(adev->dev, "Unsupported function to terminate TA\n"); return -EOPNOTSUPP;
}
ret = psp_fn_ta_terminate(psp); if (ret || context->resp_status) {
dev_err(adev->dev, "Failed to unload TA via debugfs (%d) and status (0x%X)\n",
ret, context->resp_status); if (!ret)
ret = -EINVAL;
}
if (context->mem_context.shared_buf)
psp_ta_free_shared_buf(&context->mem_context);
ret = copy_from_user((void *)&ta_type, &buf[copy_pos], sizeof(uint32_t)); if (ret) return -EFAULT;
copy_pos += sizeof(uint32_t);
ret = copy_from_user((void *)&ta_id, &buf[copy_pos], sizeof(uint32_t)); if (ret) return -EFAULT;
copy_pos += sizeof(uint32_t);
ret = copy_from_user((void *)&cmd_id, &buf[copy_pos], sizeof(uint32_t)); if (ret) return -EFAULT;
copy_pos += sizeof(uint32_t);
ret = copy_from_user((void *)&shared_buf_len, &buf[copy_pos], sizeof(uint32_t)); if (ret) return -EFAULT;
copy_pos += sizeof(uint32_t);
shared_buf = kzalloc(shared_buf_len, GFP_KERNEL); if (!shared_buf) return -ENOMEM; if (copy_from_user((void *)shared_buf, &buf[copy_pos], shared_buf_len)) {
ret = -EFAULT; goto err_free_shared_buf;
}
set_ta_context_funcs(psp, ta_type, &context);
if (!context || !context->initialized) {
dev_err(adev->dev, "TA is not initialized\n");
ret = -EINVAL; goto err_free_shared_buf;
}
if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_invoke) {
dev_err(adev->dev, "Unsupported function to invoke TA\n");
ret = -EOPNOTSUPP; goto err_free_shared_buf;
}
context->session_id = ta_id;
mutex_lock(&psp->ras_context.mutex);
ret = prep_ta_mem_context(&context->mem_context, shared_buf, shared_buf_len); if (ret) goto err_free_shared_buf;
ret = psp_fn_ta_invoke(psp, cmd_id); if (ret || context->resp_status) {
dev_err(adev->dev, "Failed to invoke TA via debugfs (%d) and status (0x%X)\n",
ret, context->resp_status); if (!ret) {
ret = -EINVAL; goto err_free_shared_buf;
}
}
if (copy_to_user((char *)&buf[copy_pos], context->mem_context.shared_buf, shared_buf_len))
ret = -EFAULT;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.