/* * ============================================================================= * The University of Illinois/NCSA * Open Source License (NCSA) * * Copyright (c) 2023, Advanced Micro Devices, Inc. * All rights reserved. * * Developed by: * * AMD Research and AMD ROC Software Development * * Advanced Micro Devices, Inc. * * www.amd.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal with 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: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in * the documentation and/or other materials provided with the distribution. * - Neither the names of , * nor the names of its contributors may be used to endorse or promote * products derived from this Software without specific prior written * permission. * * 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 CONTRIBUTORS OR COPYRIGHT HOLDERS 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 WITH THE SOFTWARE. * */ #include #include #include #include #include #include #include #include "amd_smi/amdsmi.h" #include "asm/amd_hsmp.h" #include #include #define SHOWLINESZ 256 #define CHK_AMDSMI_RET(RET) \ { \ if (RET != AMDSMI_STATUS_SUCCESS) { \ const char *err_str; \ const char **status_str; \ cout << "AMDSMI call returned " << RET << " at line " \ << __LINE__ << endl; \ status_str = amdsmi_get_esmi_err_msg(RET, &err_str); \ cout << *status_str << endl; \ return RET; \ } \ } using std::cin; using std::cout; using std::endl; using std::fixed; using std::setprecision; using std::vector; int main(int argc, char **argv) { amdsmi_status_t ret; uint32_t proto_ver; amdsmi_smu_fw_version_t smu_fw = {}; // Initialize esmi for AMD CPUs ret = amdsmi_init(AMDSMI_INIT_AMD_CPUS); CHK_AMDSMI_RET(ret) // Get all sockets uint32_t socket_count = 0; ret = amdsmi_get_cpusocket_handles(&socket_count, nullptr); CHK_AMDSMI_RET(ret) // Allocate the memory for the sockets vector sockets(socket_count); // Get the sockets of the system ret = amdsmi_get_cpusocket_handles(&socket_count, &sockets[0]); CHK_AMDSMI_RET(ret) cout << "Total Socket: " << socket_count << endl; // For each socket, get identifier and cores for (uint8_t i = 0; i < socket_count; i++) { // Get Socket info uint32_t socket_info = 0; ret = amdsmi_get_cpusocket_info(sockets[i], socket_info); CHK_AMDSMI_RET(ret) cout << "Socket " << socket_info << endl; // Get the core count available for the socket. uint32_t core_count = 0; ret = amdsmi_get_cpucore_handles(sockets[i], &core_count, nullptr); CHK_AMDSMI_RET(ret) // Allocate the memory for the cpu core handles on the socket vector processor_handles(core_count); // Get all cores of the socket ret = amdsmi_get_cpucore_handles(sockets[i], &core_count, &processor_handles[0]); CHK_AMDSMI_RET(ret) cout << "core_count=" << core_count << endl; ret = amdsmi_get_cpu_hsmp_proto_ver(sockets[i], &proto_ver); CHK_AMDSMI_RET(ret) cout<<"\n------------------------------------------"; cout<<"\n| HSMP Proto Version | "<< proto_ver <<"\t\t |"<< endl; cout<<"------------------------------------------\n"; ret = amdsmi_get_cpu_smu_fw_version(sockets[i], &smu_fw); CHK_AMDSMI_RET(ret) cout<<"\n------------------------------------------"; cout<<"\n| SMU FW Version | " <<(unsigned)smu_fw.major<<"." <<(unsigned)smu_fw.minor<<"." <<(unsigned)smu_fw.debug <<"\t\t |"< 0 && retVal < SHOWLINESZ) cout << str; else cout <<"error writing to buffer" << endl; cout<<"\n-------------------------------------------------\n"; cout<<"-----------------------------------------------------------------"; ret = amdsmi_get_cpu_cclk_limit(sockets[i], i, &cclk); CHK_AMDSMI_RET(ret) cout<<"\n| SOCKET["<(socket_power)/1000<<"\t|"; } else { err_bits |= 1 << ret; cout<<" NA (Err:" <(power_limit)/1000<<"\t|"; } else { err_bits |= 1 << ret; cout<<" NA (Err:" <(power_max)/1000<<"\t|"; } else { err_bits |= 1 << ret; cout<<" NA (Err:" <>input_power; ret = amdsmi_get_cpu_socket_power_cap_max(sockets[i], i, &power_max); CHK_AMDSMI_RET(ret) if ((ret == AMDSMI_STATUS_SUCCESS) && (input_power > power_max)) { cout<<"Input power is more than max power limit," " limiting to "<(power_max)/1000<<"Watts\n"; input_power = power_max; } ret = amdsmi_set_cpu_socket_power_cap(sockets[i], i, input_power); CHK_AMDSMI_RET(ret) if (!ret) { cout<<"Socket["<(input_power)/1000<<" Watts successfully\n"; } cout<<"\n-------------------------------------------------\n"; uint8_t mode; const char *err_str; cout <<"Enter the power efficiency mode to be set[0, 1 or 2]:\n"; cin>>mode; ret = amdsmi_set_cpu_pwr_efficiency_mode(sockets[i], i, mode); CHK_AMDSMI_RET(ret) if (ret != AMDSMI_STATUS_SUCCESS) { cout<<"Failed to set power efficiency mode for socket["<(svi_power)/1000<<"\t|"; } else { err_bits |= 1 << ret; cout<<" NA (Err:" <>boost_limit; ret = amdsmi_set_cpu_core_boostlimit(processor_handles[i], i, boost_limit); CHK_AMDSMI_RET(ret) if(ret != AMDSMI_STATUS_SUCCESS) cout<<"Failed: to set core"<<"["<>min; cout<<"\nEnter the XGMI max value to be set:\n"; cin>>max; ret = amdsmi_set_cpu_xgmi_width(sockets[i], min, max); CHK_AMDSMI_RET(ret) if(ret) cout<<"Failed: to set xGMI link width, Err["<>min_link_width; cout<<"\nEnter the GMI3 link width max value to be set:\n"; cin>>max_link_width; ret = amdsmi_set_cpu_gmi3_link_width_range(sockets[i], i, min_link_width, max_link_width); CHK_AMDSMI_RET(ret) if(ret) cout<<"Failed to set gmi3 link width for socket["<>pstate; ret = amdsmi_cpu_apb_disable(sockets[i], i, pstate); CHK_AMDSMI_RET(ret) if(ret) cout<<"Failed: to set socket["<>rate_ctrl; ret = amdsmi_set_cpu_pcie_link_rate(sockets[i], i, rate_ctrl, &prev_mode); CHK_AMDSMI_RET(ret) if(ret != AMDSMI_STATUS_SUCCESS) cout<<"Failed to set pcie link rate control for socket["<>max_pstate; cout<<"\nEnter the min_pstate to be set:\n"; cin>>min_pstate; ret = amdsmi_set_cpu_df_pstate_range(sockets[i], i, max_pstate, min_pstate); CHK_AMDSMI_RET(ret) if(ret != AMDSMI_STATUS_SUCCESS) cout<<"Failed to set df pstate range, Err["<(1) ; ret = amdsmi_get_cpu_current_io_bandwidth(sockets[i], i, io_link, &bw); CHK_AMDSMI_RET(ret) if(ret != AMDSMI_STATUS_SUCCESS) cout<<"Failed to get io bandwidth width for socket ["<(1<