diff --git a/src/runtime_src/core/common/info_platform.cpp b/src/runtime_src/core/common/info_platform.cpp index 117b3e6c70..405b55f6ab 100644 --- a/src/runtime_src/core/common/info_platform.cpp +++ b/src/runtime_src/core/common/info_platform.cpp @@ -333,32 +333,6 @@ enum_to_str(CLOCK_TYPE type) } } -void -add_clock_info(const xrt_core::device* device, ptree_type& pt) -{ - ptree_type pt_clock_array; - - try { - auto raw = xrt_core::device_query(device); - if (raw.empty()) - return; - - ptree_type pt_clocks; - auto clock_topology = reinterpret_cast(raw.data()); - for (int i = 0; i < clock_topology->m_count; i++) { - ptree_type pt_clock; - pt_clock.add("id", clock_topology->m_clock_freq[i].m_name); - pt_clock.add("description", enum_to_str(static_cast(clock_topology->m_clock_freq[i].m_type))); - pt_clock.add("freq_mhz", clock_topology->m_clock_freq[i].m_freq_Mhz); - pt_clock_array.push_back(std::make_pair("", pt_clock)); - } - pt.put_child("clocks", pt_clock_array); - } - catch (const xq::no_such_key&) { - // ignoring if not available: Edge Case - } -} - void add_tops_info(const xrt_core::device* device, ptree_type& pt) { @@ -463,7 +437,8 @@ add_platform_info(const xrt_core::device* device, ptree_type& pt_platform_array) else add_controller_info(device, pt_platform); add_mac_info(device, pt_platform); - add_clock_info(device, pt_platform); + auto pt_clock_array = xrt_core::platform::get_clock_info(device); + pt_platform.put_child("clocks", pt_clock_array); add_config_info(device, pt_platform); break; } @@ -484,6 +459,33 @@ add_platform_info(const xrt_core::device* device, ptree_type& pt_platform_array) namespace xrt_core { namespace platform { +ptree_type +get_clock_info(const xrt_core::device* device) +{ + ptree_type pt; + + try { + auto raw = xrt_core::device_query(device); + if (raw.empty()) + return pt; + + ptree_type pt_clock_array; + auto clock_topology = reinterpret_cast(raw.data()); + for (int i = 0; i < clock_topology->m_count; i++) { + ptree_type pt_clock; + pt_clock.add("id", clock_topology->m_clock_freq[i].m_name); + pt_clock.add("description", enum_to_str(static_cast(clock_topology->m_clock_freq[i].m_type))); + pt_clock.add("freq_mhz", clock_topology->m_clock_freq[i].m_freq_Mhz); + pt_clock_array.push_back(std::make_pair("", pt_clock)); + } + pt.put_child("clocks", pt_clock_array); + } + catch (const xq::no_such_key&) { + // ignoring if not available: Edge Case + } + return pt; +} + ptree_type platform_info(const xrt_core::device* device) { diff --git a/src/runtime_src/core/common/info_platform.h b/src/runtime_src/core/common/info_platform.h index 291e008ab0..b0551ff973 100644 --- a/src/runtime_src/core/common/info_platform.h +++ b/src/runtime_src/core/common/info_platform.h @@ -31,6 +31,10 @@ XRT_CORE_COMMON_EXPORT boost::property_tree::ptree pcie_info(const xrt_core::device* device); +XRT_CORE_COMMON_EXPORT +boost::property_tree::ptree +get_clock_info(const xrt_core::device* device); + }} // platform, xrt #endif diff --git a/src/runtime_src/core/tools/xbutil2/CMakeLists.txt b/src/runtime_src/core/tools/xbutil2/CMakeLists.txt index 82d210be02..2a09ce58d0 100644 --- a/src/runtime_src/core/tools/xbutil2/CMakeLists.txt +++ b/src/runtime_src/core/tools/xbutil2/CMakeLists.txt @@ -49,6 +49,7 @@ file(GLOB XBUTIL_V2_SUBCMD_FILES "OO_HostMem.cpp" "OO_Performance.cpp" "OO_Preemption.cpp" + "OO_Reports.cpp" ) # Merge the files into one collection diff --git a/src/runtime_src/core/tools/xbutil2/OO_Reports.cpp b/src/runtime_src/core/tools/xbutil2/OO_Reports.cpp new file mode 100644 index 0000000000..e2543fe31a --- /dev/null +++ b/src/runtime_src/core/tools/xbutil2/OO_Reports.cpp @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. + +// ------ I N C L U D E F I L E S ------------------------------------------- +// Local - Include Files +#include "OO_Reports.h" +#include "tools/common/XBUtilitiesCore.h" +#include "tools/common/XBUtilities.h" +#include "tools/common/XBHelpMenusCore.h" +#include "core/common/info_platform.h" + +// 3rd Party Library - Include Files +#include +#include +namespace po = boost::program_options; +using bpt = boost::property_tree::ptree; + +// ----- C L A S S M E T H O D S ------------------------------------------- + +OO_Reports::OO_Reports( const std::string &_longName, bool _isHidden ) + : OptionOptions(_longName, _isHidden, "Hidden reports") + , m_device("") + , m_action("") + , m_help(false) +{ + m_optionsDescription.add_options() + ("device,d", boost::program_options::value(&m_device), "The Bus:Device.Function (e.g., 0000:d8:00.0) device of interest") + ("help", boost::program_options::bool_switch(&m_help), "Help to use this sub-command") + ("mode", boost::program_options::value(&m_action)->required(), "Action to perform: clocks") + ; + + m_positionalOptions. + add("mode", 1 /* max_count */) + ; +} + +void +OO_Reports::execute(const SubCmdOptions& _options) const +{ + XBUtilities::verbose("SubCommand option: report"); + + XBUtilities::verbose("Option(s):"); + for (auto & aString : _options) + XBUtilities::verbose(std::string(" ") + aString); + + // Honor help option first + if (std::find(_options.begin(), _options.end(), "--help") != _options.end()) { + printHelp(); + return; + } + + // Parse sub-command ... + po::variables_map vm; + + try { + po::options_description all_options("All Options"); + all_options.add(m_optionsDescription); + po::command_line_parser parser(_options); + XBUtilities::process_arguments(vm, parser, all_options, m_positionalOptions, true); + } catch(boost::program_options::error&) { + if(m_help) { + printHelp(); + throw xrt_core::error(std::errc::operation_canceled); + } + // Exit if neither action or device specified + if(m_action.empty()) { + std::cerr << boost::format("ERROR: the required argument for option '--report' is missing\n"); + printHelp(); + throw xrt_core::error(std::errc::operation_canceled); + } + } + + // Find device of interest + std::shared_ptr device; + + try { + device = XBUtilities::get_device(boost::algorithm::to_lower_copy(m_device), true /*inUserDomain*/); + } catch (const std::runtime_error& e) { + // Catch only the exceptions that we have generated earlier + std::cerr << boost::format("ERROR: %s\n") % e.what(); + throw xrt_core::error(std::errc::operation_canceled); + } + + try { + if (boost::iequals(m_action, "clock")) { + bpt empty_tree; + auto clocks = xrt_core::platform::get_clock_info(device.get()); + const bpt& pt_clock_array = clocks.get_child("clocks", empty_tree); + if(pt_clock_array.empty()) + return; + + std::cout << std::endl << "Clocks" << std::endl; + for (const auto& kc : pt_clock_array) { + const bpt& pt_clock = kc.second; + std::string clock_name_type = pt_clock.get("id"); + std::cout << boost::format(" %-23s: %3s MHz\n") % clock_name_type % pt_clock.get("freq_mhz"); + } + } + else { + throw xrt_core::error(boost::str(boost::format("Invalid report value: '%s'\n") % m_action)); + } + } + catch(const xrt_core::error& e) { + std::cerr << boost::format("\nERROR: %s\n") % e.what(); + printHelp(); + throw xrt_core::error(std::errc::operation_canceled); + } +} diff --git a/src/runtime_src/core/tools/xbutil2/OO_Reports.h b/src/runtime_src/core/tools/xbutil2/OO_Reports.h new file mode 100644 index 0000000000..b2a02294a7 --- /dev/null +++ b/src/runtime_src/core/tools/xbutil2/OO_Reports.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. + +#ifndef __OO_Reports_h_ +#define __OO_Reports_h_ + +#include "tools/common/OptionOptions.h" + +class OO_Reports : public OptionOptions { + public: + virtual void execute( const SubCmdOptions &_options ) const; + + public: + OO_Reports( const std::string &_longName, bool _isHidden = false); + + private: + std::string m_device; + std::string m_action; + bool m_help; +}; + +#endif diff --git a/src/runtime_src/core/tools/xbutil2/SubCmdAdvanced.cpp b/src/runtime_src/core/tools/xbutil2/SubCmdAdvanced.cpp index 8b6ed13f3b..9c1d3b4f0d 100644 --- a/src/runtime_src/core/tools/xbutil2/SubCmdAdvanced.cpp +++ b/src/runtime_src/core/tools/xbutil2/SubCmdAdvanced.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (C) 2020-2022 Xilinx, Inc -// Copyright (C) 2022-2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (C) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. // ------ I N C L U D E F I L E S ------------------------------------------- // Local - Include Files @@ -8,6 +8,7 @@ #include "OO_AieRegRead.h" #include "OO_MemRead.h" #include "OO_MemWrite.h" +#include "OO_Reports.h" #include "SubCmdAdvanced.h" #include "common/device.h" @@ -51,6 +52,7 @@ SubCmdAdvanced::SubCmdAdvanced(bool _isHidden, bool _isDepricated, bool _isPreli addSubOption(std::make_shared("read-mem")); addSubOption(std::make_shared("write-mem")); + addSubOption(std::make_shared("report")); // Only defined for embedded platform #ifndef ENABLE_NATIVE_SUBCMDS_AND_REPORTS addSubOption(std::make_shared("read-aie-reg")); diff --git a/src/runtime_src/core/tools/xbutil2/xbutil.cpp b/src/runtime_src/core/tools/xbutil2/xbutil.cpp index 540c22428f..2b3bb9c9d9 100644 --- a/src/runtime_src/core/tools/xbutil2/xbutil.cpp +++ b/src/runtime_src/core/tools/xbutil2/xbutil.cpp @@ -62,7 +62,7 @@ R"( }] },{ "advanced":[{ - "suboption": ["read-aie-reg", "aie-clock"] + "suboption": ["read-aie-reg", "aie-clock", "report"] }] },{ "validate": [{