diff --git a/src/runtime_src/core/common/device.cpp b/src/runtime_src/core/common/device.cpp index 124793467d3..1e0981baf9f 100644 --- a/src/runtime_src/core/common/device.cpp +++ b/src/runtime_src/core/common/device.cpp @@ -12,7 +12,6 @@ #include "utils.h" #include "xclbin_parser.h" #include "xclbin_swemu.h" - #include "core/include/ert.h" #include "core/include/xrt.h" #include "core/include/xclbin.h" @@ -137,23 +136,48 @@ load_xclbin(const xrt::xclbin& xclbin) } } +/* This function reads the axlf buffer + * for the specific uuid passed. + */ void device:: load_xclbin(const uuid& xclbin_id) { - auto uuid_loaded = get_xclbin_uuid(); - if (uuid_compare(uuid_loaded.get(), xclbin_id.get())) - throw error(ENODEV, "specified xclbin is not loaded"); + /* UUID comparision happens at low level where the + * the query for axlf buffer sent for this specific uuid. + */ #ifdef XRT_ENABLE_AIE - auto xclbin_full = xrt_core::device_query(this); - if (xclbin_full.empty()) - throw error(ENODEV, "no cached xclbin data"); + uint64_t skd_uuid_ptr = reinterpret_cast(xclbin_id.get()); + const axlf* skd_axlf_ptr; + uint32_t axlf_size; - const axlf* top = reinterpret_cast(xclbin_full.data()); + /* Query for axlf buffer size Ioctl for this UUID parameter */ + try { + axlf_size = xrt_core::device_query(this, skd_uuid_ptr); + } + catch (const std::exception &e) { + std::cerr << boost::format("ERROR: Failed to get axlf size (%lx)\n %s\n") % xclbin_id.get() % e.what(); + throw xrt_core::error(std::errc::operation_canceled); + } + if(axlf_size == 0) + { + std::cerr << boost::format("ERROR: UUID not found (%lx)\n %s\n") % xclbin_id.get(); + throw xrt_core::error(std::errc::operation_canceled); + } + /* Initialize the axlf buffer and query axlf for the specified UUID */ + std::vector buf(axlf_size, 0); + + if (auto ret = xrt_core::device_query(this, skd_uuid_ptr, reinterpret_cast(buf.data()))) + { + std::cerr << boost::format("ERROR: Failed to get xclbin for uuid (%lx)\n %s\n") % xclbin_id.get(); + throw xrt_core::error(std::errc::operation_canceled); + } + + skd_axlf_ptr = reinterpret_cast (buf.data()); try { // set before register_axlf is called via load_axlf_meta - m_xclbin = xrt::xclbin{top}; + m_xclbin = xrt::xclbin{skd_axlf_ptr}; load_axlf_meta(m_xclbin.get_axlf()); } catch (const std::exception&) { diff --git a/src/runtime_src/core/common/query_requests.h b/src/runtime_src/core/common/query_requests.h index df9d0917fe5..a1943a1ac8f 100644 --- a/src/runtime_src/core/common/query_requests.h +++ b/src/runtime_src/core/common/query_requests.h @@ -324,6 +324,8 @@ enum class key_type kernel_max_bandwidth_mbps, sub_device_path, read_trace_data, + aie_skd_xclbin, + skd_axlf_size, noop }; @@ -3819,6 +3821,36 @@ struct read_trace_data : request virtual std::any get(const device*, const std::any&) const = 0; }; + +/* SKD Request to load xclbin for a specific UUID */ +struct aie_skd_xclbin : request +{ + using result_type = uint32_t; + using skd_uuid_ptr_type = uint64_t; + using skd_axlf_ptr_type = uint64_t; + + static const key_type key = key_type::aie_skd_xclbin; + struct args { + uint64_t skd_uuid_ptr; + uint64_t skd_axlf_ptr; + }; + + virtual std::any + get(const device*, const std::any& skd_uuid_ptr, const std::any& skd_axlf_ptr) const = 0; +}; + +/* SKD Request to read the axlf size for a specific uuid */ +struct skd_axlf_size : request +{ + using skd_uuid_ptr_type = uint64_t; + using result_type = uint32_t; + + static const key_type key = key_type::skd_axlf_size; + + virtual std::any + get(const device*, const std::any& skd_uuid_ptr) const = 0; +}; + } // query } // xrt_core diff --git a/src/runtime_src/core/common/xrt_profiling.h b/src/runtime_src/core/common/xrt_profiling.h index 35ee16e7c88..983c41ec7e8 100644 --- a/src/runtime_src/core/common/xrt_profiling.h +++ b/src/runtime_src/core/common/xrt_profiling.h @@ -56,6 +56,11 @@ XCL_DRIVER_DLLESPEC int xclReadTraceData(xclDeviceHandle handle, void* traceBuf, XCL_DRIVER_DLLESPEC int xclGetSubdevPath(xclDeviceHandle handle, const char* subdev, uint32_t idx, char* path, size_t size); +XCL_DRIVER_DLLESPEC int xclgetAIESkdXclbin(xclDeviceHandle handle, uint64_t skd_uuid_ptr, uint64_t skd_axlf_ptr); + +XCL_DRIVER_DLLESPEC int xclgetAIESkdAxlfSize(xclDeviceHandle handle, uint64_t skd_uuid_ptr); + + #ifdef __cplusplus } #endif diff --git a/src/runtime_src/core/edge/drm/zocl/common/zocl_drv.c b/src/runtime_src/core/edge/drm/zocl/common/zocl_drv.c index 1aefb7b0b7c..b727c09aa9d 100644 --- a/src/runtime_src/core/edge/drm/zocl/common/zocl_drv.c +++ b/src/runtime_src/core/edge/drm/zocl/common/zocl_drv.c @@ -1002,6 +1002,10 @@ static const struct drm_ioctl_desc zocl_ioctls[] = { DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(ZOCL_SET_CU_READONLY_RANGE, zocl_set_cu_read_only_range_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(ZOCL_AIE_SKD_XCLBIN, zocl_aie_skd_xclbin_ioctl, + DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(ZOCL_SKD_AXLF_SIZE, zocl_skd_axlf_size_ioctl, + DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), }; static const struct file_operations zocl_driver_fops = { diff --git a/src/runtime_src/core/edge/drm/zocl/common/zocl_ioctl.c b/src/runtime_src/core/edge/drm/zocl/common/zocl_ioctl.c index 17236415189..ceb9b3c8114 100644 --- a/src/runtime_src/core/edge/drm/zocl/common/zocl_ioctl.c +++ b/src/runtime_src/core/edge/drm/zocl/common/zocl_ioctl.c @@ -150,3 +150,19 @@ zocl_set_cu_read_only_range_ioctl(struct drm_device *dev, void *data, ret = zocl_kds_set_cu_read_range(zdev, info->cu_index, info->start, info->size); return ret; } + +int +zocl_aie_skd_xclbin_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) +{ + struct drm_zocl_dev *zdev = ZOCL_GET_ZDEV(dev); + + return zocl_aie_skd_xclbin(zdev, data); +} + +int +zocl_skd_axlf_size_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) +{ + struct drm_zocl_dev *zdev = ZOCL_GET_ZDEV(dev); + + return zocl_skd_axlf_size(zdev, data); +} diff --git a/src/runtime_src/core/edge/drm/zocl/edge/zocl_aie.c b/src/runtime_src/core/edge/drm/zocl/edge/zocl_aie.c index fe6b20c55e1..bc21f39a1e2 100644 --- a/src/runtime_src/core/edge/drm/zocl/edge/zocl_aie.c +++ b/src/runtime_src/core/edge/drm/zocl/edge/zocl_aie.c @@ -17,6 +17,7 @@ #include "zocl_aie.h" #include "xrt_xclbin.h" #include "xclbin.h" +#include "zocl_xclbin.h" #ifndef __NONE_PETALINUX__ #include @@ -552,6 +553,103 @@ int zocl_aie_freqscale(struct drm_zocl_dev *zdev, void *data) } } +int zocl_aie_skd_xclbin(struct drm_zocl_dev *zdev, void *data) +{ + struct drm_zocl_aie_skd_xclbin *args = data; + struct drm_zocl_slot *zocl_slot = NULL; + uuid_t *slot_uuid = NULL; + uuid_t *skd_uuid = NULL; + int i, slot_id = MAX_PR_SLOT_NUM, ret = 0; + void *uuid_ptr = (void *)(uintptr_t)args->skd_uuid_ptr; + + skd_uuid = vmalloc(sizeof(uuid_t)); + if (!skd_uuid) + return -ENOMEM; + + ret = copy_from_user(skd_uuid, uuid_ptr, sizeof(uuid_t)); + if (ret) { + vfree(skd_uuid); + return ret; + } + mutex_lock(&zdev->aie_lock); + + for (i = 0; i < MAX_PR_SLOT_NUM; i++) { + struct drm_zocl_slot *slot = NULL; + slot = zdev->pr_slot[i]; + if (!slot) + continue; + mutex_lock(&zdev->pr_slot[i]->slot_xclbin_lock); + slot_uuid = zocl_xclbin_get_uuid(zdev->pr_slot[i]); + if(slot_uuid) { + if(uuid_equal(slot_uuid, skd_uuid)) { + slot_id = i; + mutex_unlock(&zdev->pr_slot[i]->slot_xclbin_lock); + break; + } + } + mutex_unlock(&zdev->pr_slot[i]->slot_xclbin_lock); + } + zocl_slot = zdev->pr_slot[slot_id]; + ret = copy_to_user(args->skd_axlf_ptr, (char *)zocl_slot->axlf, zocl_slot->axlf_size); + if (ret) { + vfree(skd_uuid); + mutex_unlock(&zdev->aie_lock); + return ret; + } + mutex_unlock(&zdev->aie_lock); + vfree(skd_uuid); + return 0; +} + +int zocl_skd_axlf_size(struct drm_zocl_dev *zdev, void *data) +{ + struct drm_zocl_skd_axlf_size *args = data; + struct drm_zocl_slot *zocl_slot = NULL; + uuid_t *slot_uuid = NULL; + uuid_t *skd_uuid = NULL; + int i, slot_id = MAX_PR_SLOT_NUM, ret = 0; + void *uuid_ptr = (void *)(uintptr_t)args->skd_uuid_ptr; + + skd_uuid = vmalloc(sizeof(uuid_t)); + if (!skd_uuid) + return -ENOMEM; + + ret = copy_from_user(skd_uuid, uuid_ptr, sizeof(uuid_t)); + if (ret) { + vfree(skd_uuid); + return ret; + } + mutex_lock(&zdev->aie_lock); + + for (i = 0; i < MAX_PR_SLOT_NUM; i++) { + struct drm_zocl_slot *slot = NULL; + slot = zdev->pr_slot[i]; + if (!slot) + continue; + mutex_lock(&zdev->pr_slot[i]->slot_xclbin_lock); + slot_uuid = zocl_xclbin_get_uuid(zdev->pr_slot[i]); + if(slot_uuid) { + if(uuid_equal(slot_uuid, skd_uuid)) { + slot_id = i; + mutex_unlock(&zdev->pr_slot[i]->slot_xclbin_lock); + break; + } + } + mutex_unlock(&zdev->pr_slot[i]->slot_xclbin_lock); + } + if(i == MAX_PR_SLOT_NUM) + { + DRM_ERROR(" %s: UUID not found \n",__func__); + mutex_unlock(&zdev->aie_lock); + return -ENODEV; + } + zocl_slot = zdev->pr_slot[slot_id]; + args->axlf_size = zocl_slot->axlf_size; + + mutex_unlock(&zdev->aie_lock); + return 0; +} + int zocl_aie_kds_add_graph_context(struct drm_zocl_dev *zdev, u32 gid, u32 ctx_code, struct kds_client *client) @@ -843,4 +941,4 @@ zocl_init_aie(struct drm_zocl_dev *zdev) zdev->aie_information = aie; return 0; -} +} \ No newline at end of file diff --git a/src/runtime_src/core/edge/drm/zocl/include/zocl_drv.h b/src/runtime_src/core/edge/drm/zocl/include/zocl_drv.h index edd1b517d67..7c46a08bbb7 100644 --- a/src/runtime_src/core/edge/drm/zocl/include/zocl_drv.h +++ b/src/runtime_src/core/edge/drm/zocl/include/zocl_drv.h @@ -288,6 +288,8 @@ int zocl_inject_error(struct drm_zocl_dev *zdev, void *data, int zocl_init_error(struct drm_zocl_dev *zdev); void zocl_fini_error(struct drm_zocl_dev *zdev); int zocl_insert_error_record(struct drm_zocl_dev *zdev, xrtErrorCode err_code); +int zocl_aie_skd_xclbin(struct drm_zocl_dev *zdev, void *data); +int zocl_skd_axlf_size(struct drm_zocl_dev *zdev, void *data); /* zocl_kds.c */ int zocl_init_sched(struct drm_zocl_dev *zdev); diff --git a/src/runtime_src/core/edge/drm/zocl/include/zocl_ioctl.h b/src/runtime_src/core/edge/drm/zocl/include/zocl_ioctl.h index 0200eb8657e..ff71d3d09e0 100644 --- a/src/runtime_src/core/edge/drm/zocl/include/zocl_ioctl.h +++ b/src/runtime_src/core/edge/drm/zocl/include/zocl_ioctl.h @@ -61,4 +61,8 @@ int zocl_aie_freqscale_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); int zocl_set_cu_read_only_range_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); +int +zocl_aie_skd_xclbin_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); +int +zocl_skd_axlf_size_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); #endif diff --git a/src/runtime_src/core/edge/drm/zocl/zert/zocl_sk.c b/src/runtime_src/core/edge/drm/zocl/zert/zocl_sk.c index 168ccd35100..a03c12f6d67 100644 --- a/src/runtime_src/core/edge/drm/zocl/zert/zocl_sk.c +++ b/src/runtime_src/core/edge/drm/zocl/zert/zocl_sk.c @@ -60,16 +60,17 @@ zocl_sk_getcmd_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) cmd = scmd->skc_packet; /* Look for slot_id corresponding to UUID */ - for (i = 0;i < MAX_PR_SLOT_NUM;i++) { + for (i = 0; i < MAX_PR_SLOT_NUM; i++) { mutex_lock(&zdev->pr_slot[i]->slot_xclbin_lock); slot_uuid = zocl_xclbin_get_uuid(zdev->pr_slot[i]); if(slot_uuid) { - mutex_unlock(&zdev->pr_slot[i]->slot_xclbin_lock); if(uuid_equal(slot_uuid,(xuid_t *)cmd->sk_uuid)) { slot_id = i; + mutex_unlock(&zdev->pr_slot[i]->slot_xclbin_lock); break; } } + mutex_unlock(&zdev->pr_slot[i]->slot_xclbin_lock); } if (slot_id == MAX_PR_SLOT_NUM) { @@ -129,10 +130,10 @@ zocl_sk_getcmd_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) kdata->cu_nums = cmd->num_cus; kdata->bohdl = bohdl; kdata->meta_bohdl = meta_bohdl; - // Pass physical slot 0 UUID to SKD - Currently we only support 1 physical slot - mutex_lock(&zdev->pr_slot[0]->slot_xclbin_lock); - phy_slot_uuid = zocl_xclbin_get_uuid(zdev->pr_slot[0]); - mutex_unlock(&zdev->pr_slot[0]->slot_xclbin_lock); + // Pass physical slot_id UUID to SKD - Currently we only support 1 physical slot + mutex_lock(&zdev->pr_slot[slot_id]->slot_xclbin_lock); + phy_slot_uuid = zocl_xclbin_get_uuid(zdev->pr_slot[slot_id]); + mutex_unlock(&zdev->pr_slot[slot_id]->slot_xclbin_lock); memcpy(kdata->uuid,phy_slot_uuid,sizeof(kdata->uuid)); snprintf(kdata->name, ZOCL_MAX_NAME_LENGTH, "%s", diff --git a/src/runtime_src/core/edge/include/zynq_ioctl.h b/src/runtime_src/core/edge/include/zynq_ioctl.h index 098dea39ad7..15fc51428be 100644 --- a/src/runtime_src/core/edge/include/zynq_ioctl.h +++ b/src/runtime_src/core/edge/include/zynq_ioctl.h @@ -124,6 +124,10 @@ enum drm_zocl_ops { DRM_ZOCL_AIE_FREQSCALE, /* Set CU read-only range */ DRM_ZOCL_SET_CU_READONLY_RANGE, + /* Read xclbin for a specific uuid */ + DRM_ZOCL_AIE_SKD_XCLBIN, + /* Read Axlf size */ + DRM_ZOCL_SKD_AXLF_SIZE, DRM_ZOCL_NUM_IOCTLS }; @@ -548,6 +552,16 @@ struct drm_zocl_error_inject { uint16_t err_class; }; +struct drm_zocl_aie_skd_xclbin { + uint64_t skd_axlf_ptr; + uint64_t skd_uuid_ptr; +}; + +struct drm_zocl_skd_axlf_size { + uint64_t skd_uuid_ptr; + uint32_t axlf_size; +}; + #define DRM_IOCTL_ZOCL_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + \ DRM_ZOCL_CREATE_BO, \ struct drm_zocl_create_bo) @@ -596,4 +610,8 @@ struct drm_zocl_error_inject { DRM_ZOCL_AIE_FREQSCALE, struct drm_zocl_aie_freq_scale) #define DRM_IOCTL_ZOCL_SET_CU_READONLY_RANGE DRM_IOWR(DRM_COMMAND_BASE + \ DRM_ZOCL_SET_CU_READONLY_RANGE, struct drm_zocl_set_cu_range) +#define DRM_IOCTL_ZOCL_AIE_SKD_XCLBIN DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_ZOCL_AIE_SKD_XCLBIN, struct drm_zocl_aie_skd_xclbin) +#define DRM_IOCTL_ZOCL_SKD_AXLF_SIZE DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_ZOCL_SKD_AXLF_SIZE, struct drm_zocl_skd_axlf_size) #endif diff --git a/src/runtime_src/core/edge/user/device_linux.cpp b/src/runtime_src/core/edge/user/device_linux.cpp index 4c9d0aa52b4..b007fbf07f7 100644 --- a/src/runtime_src/core/edge/user/device_linux.cpp +++ b/src/runtime_src/core/edge/user/device_linux.cpp @@ -10,6 +10,7 @@ #include "core/common/query_requests.h" #include "core/common/xrt_profiling.h" #include "shim.h" +#include "core/include/xrt/xrt_uuid.h" #include #include @@ -841,6 +842,45 @@ struct read_trace_data } }; +struct aie_skd_xclbin +{ + using result_type = query::aie_skd_xclbin::result_type; + XAie_DevInst* devInst; // AIE Device Instance + + static result_type + get(const xrt_core::device* device, key_type key, const std::any& skd_uuid_ptr, const std::any& skd_axlf_ptr) + { +#if defined(XRT_ENABLE_AIE) + result_type ret = 0; + /* Get the Axlf Buffer */ + ret = xclgetAIESkdXclbin(device->get_user_handle(), std::any_cast(skd_uuid_ptr), + std::any_cast(skd_axlf_ptr)); +#else + throw xrt_core::error(-EINVAL, "AIE is not enabled for this device"); +#endif + return ret; + } +}; + +struct skd_axlf_size +{ + using result_type = query::skd_axlf_size::result_type; + XAie_DevInst* devInst; // AIE Device Instance + + static result_type + get(const xrt_core::device* device, key_type key, const std::any& skd_uuid_ptr) + { +#if defined(XRT_ENABLE_AIE) + result_type axlf_size = 0; + /* Read the Axlf size */ + axlf_size = xclgetAIESkdAxlfSize(device->get_user_handle(), std::any_cast(skd_uuid_ptr)); +#else + throw xrt_core::error(-EINVAL, "AIE is not enabled for this device"); +#endif + return axlf_size; + } +}; + // Specialize for other value types. template struct sysfs_fcn @@ -1046,6 +1086,8 @@ initialize_query_table() emplace_func0_request(); emplace_func4_request(); emplace_func4_request(); + emplace_func2_request(); + emplace_func4_request(); emplace_func4_request(); emplace_func4_request(); } diff --git a/src/runtime_src/core/edge/user/shim.cpp b/src/runtime_src/core/edge/user/shim.cpp index ceda5ffd43e..5bba4f9bf83 100644 --- a/src/runtime_src/core/edge/user/shim.cpp +++ b/src/runtime_src/core/edge/user/shim.cpp @@ -1862,6 +1862,35 @@ setAIEAccessMode(xrt::aie::access_mode am) access_mode = am; } +int +shim:: +xclgetAIESkdAxlfSize(uint64_t skd_uuid_ptr) +{ + int ret = 0; + struct drm_zocl_skd_axlf_size aie_arg = {skd_uuid_ptr, 0}; + + ret = ioctl(mKernelFD, DRM_IOCTL_ZOCL_SKD_AXLF_SIZE, &aie_arg); + if (ret) + { + xclLog(XRT_ERROR, "%s:ioctl return %d", __func__, ret); + return -errno; + } + return aie_arg.axlf_size; +} + +int +shim:: +xclgetAIESkdXclbin(uint64_t skd_uuid_ptr, uint64_t skd_axlf_ptr) +{ + int ret = 0; + struct drm_zocl_aie_skd_xclbin aie_arg; + + aie_arg.skd_uuid_ptr = skd_uuid_ptr; + aie_arg.skd_axlf_ptr = skd_axlf_ptr; + + ret = ioctl(mKernelFD, DRM_IOCTL_ZOCL_AIE_SKD_XCLBIN, &aie_arg); + return ret ? -errno : ret; +} #endif } // end namespace ZYNQ @@ -2827,3 +2856,18 @@ xclErrorClear(xclDeviceHandle handle) return drv->xclErrorClear(); } + +int +xclgetAIESkdXclbin(xclDeviceHandle handle, uint64_t skd_uuid_ptr, uint64_t skd_axlf_ptr) +{ + ZYNQ::shim *drv = ZYNQ::shim::handleCheck(handle); + return (drv) ? drv->xclgetAIESkdXclbin(skd_uuid_ptr, skd_axlf_ptr) : -EINVAL; +} + +int +xclgetAIESkdAxlfSize(xclDeviceHandle handle, uint64_t skd_uuid_ptr) +{ + ZYNQ::shim *drv = ZYNQ::shim::handleCheck(handle); + return (drv) ? drv->xclgetAIESkdAxlfSize(skd_uuid_ptr) : -EINVAL; +} + diff --git a/src/runtime_src/core/edge/user/shim.h b/src/runtime_src/core/edge/user/shim.h index 7d047ee1fc7..2b608fa75b5 100644 --- a/src/runtime_src/core/edge/user/shim.h +++ b/src/runtime_src/core/edge/user/shim.h @@ -423,6 +423,8 @@ class shim { static shim *handleCheck(void *handle, bool checkDrmFd = true); int xclIPName2Index(const char *name); int xclIPSetReadRange(uint32_t ipIndex, uint32_t start, uint32_t size); + int xclgetAIESkdAxlfSize(uint64_t skd_uuid_ptr); + int xclgetAIESkdXclbin(uint64_t skd_uuid_ptr, uint64_t skd_axlf_ptr); // Application debug path functionality for xbutil size_t xclDebugReadCheckers(xdp::LAPCCounterResults* aCheckerResults);