| /* |
| * SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & |
| * AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| // NSM: Nvidia Message type |
| // - Network Ports [Type 1] |
| // - PCI links [Type 2] |
| // - Platform environments [Type 3] |
| // - Diagnostics [Type 4] |
| // - Device configuration [Type 5] |
| |
| #include "nsm_config_cmd.hpp" |
| |
| #include "base.h" |
| #include "device-configuration.h" |
| #include "platform-environmental.h" |
| |
| #include "cmd_helper.hpp" |
| #include "utils.hpp" |
| |
| #include <endian.h> |
| |
| #include <CLI/CLI.hpp> |
| |
| #include <algorithm> |
| #include <cctype> |
| #include <cstdint> |
| #include <cstdlib> |
| #include <cstring> |
| #include <ctime> |
| #include <string> |
| #include <vector> |
| |
| namespace nsmtool |
| { |
| |
| namespace config |
| { |
| |
| namespace |
| { |
| |
| using namespace nsmtool::helper; |
| std::vector<std::unique_ptr<CommandInterface>> commands; |
| |
| bool parseHexToBytes(const std::string& hex, std::vector<uint8_t>& out) |
| { |
| out.clear(); |
| if (hex.empty()) |
| { |
| return true; |
| } |
| if (hex.size() % 2 != 0) |
| { |
| return false; |
| } |
| for (size_t i = 0; i < hex.size(); i += 2) |
| { |
| char pair[3] = {hex[i], hex[i + 1], '\0'}; |
| char* end = nullptr; |
| unsigned long v = std::strtoul(pair, &end, 16); |
| if (end != pair + 2 || v > 255) |
| { |
| return false; |
| } |
| out.push_back(static_cast<uint8_t>(v)); |
| } |
| return true; |
| } |
| |
| } // namespace |
| |
| class SetErrorInjectionModeV1 : public CommandInterface |
| { |
| public: |
| ~SetErrorInjectionModeV1() = default; |
| SetErrorInjectionModeV1() = delete; |
| SetErrorInjectionModeV1(const SetErrorInjectionModeV1&) = delete; |
| SetErrorInjectionModeV1(SetErrorInjectionModeV1&&) = default; |
| SetErrorInjectionModeV1& operator=(const SetErrorInjectionModeV1&) = delete; |
| SetErrorInjectionModeV1& operator=(SetErrorInjectionModeV1&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetErrorInjectionModeV1(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| auto modeGroup = app->add_option_group( |
| "Required", "Global error injection mode knob"); |
| |
| mode = 0; |
| modeGroup->add_option("-M, --mode", mode, "Disable - 0 / Enable - 1"); |
| modeGroup->require_option(1); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_set_error_injection_mode_v1_req)); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_error_injection_mode_v1_req(instanceId, mode, |
| request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_set_error_injection_mode_v1_resp( |
| responsePtr, payloadLength, &cc, &reason_code); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + sizeof(nsm_common_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| uint8_t mode; |
| }; |
| |
| class GetErrorInjectionModeV1 : public CommandInterface |
| { |
| public: |
| ~GetErrorInjectionModeV1() = default; |
| GetErrorInjectionModeV1() = delete; |
| GetErrorInjectionModeV1(const GetErrorInjectionModeV1&) = delete; |
| GetErrorInjectionModeV1(GetErrorInjectionModeV1&&) = default; |
| GetErrorInjectionModeV1& operator=(const GetErrorInjectionModeV1&) = delete; |
| GetErrorInjectionModeV1& operator=(GetErrorInjectionModeV1&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetErrorInjectionModeV1(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| {} |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_error_injection_mode_v1_req(instanceId, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| nsm_error_injection_mode_v1 data; |
| |
| auto rc = decode_get_error_injection_mode_v1_resp( |
| responsePtr, payloadLength, &cc, &reason_code, &data); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_error_injection_mode_v1_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["Mode"] = bool(data.mode); |
| result["Persistent"] = bool(data.flags.bits.bit0); |
| nsmtool::helper::DisplayInJson(result); |
| } |
| }; |
| |
| class GetSupportedErrorInjectionTypesV1 : public CommandInterface |
| { |
| public: |
| ~GetSupportedErrorInjectionTypesV1() = default; |
| GetSupportedErrorInjectionTypesV1() = delete; |
| GetSupportedErrorInjectionTypesV1( |
| const GetSupportedErrorInjectionTypesV1&) = delete; |
| GetSupportedErrorInjectionTypesV1(GetSupportedErrorInjectionTypesV1&&) = |
| default; |
| GetSupportedErrorInjectionTypesV1& |
| operator=(const GetSupportedErrorInjectionTypesV1&) = delete; |
| GetSupportedErrorInjectionTypesV1& |
| operator=(GetSupportedErrorInjectionTypesV1&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetSupportedErrorInjectionTypesV1(const char* type, |
| const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| {} |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_supported_error_injection_types_v1_req(instanceId, |
| request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| nsm_error_injection_types_mask data; |
| |
| auto rc = decode_get_error_injection_types_v1_resp( |
| responsePtr, payloadLength, &cc, &reason_code, &data); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_error_injection_types_mask_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["DRAM and SRAM errors injection supported"] = |
| bool((data.mask[0] >> EI_MEMORY_ERRORS) & 0x01); |
| result["PCI link error injection supported"] = |
| bool((data.mask[0] >> EI_PCI_ERRORS) & 0x01); |
| result["Link error injection supported"] = |
| bool((data.mask[0] >> EI_NVLINK_ERRORS) & 0x01); |
| result["Thermal error injection supported"] = |
| bool((data.mask[0] >> EI_THERMAL_ERRORS) & 0x01); |
| result["Device error injection supported"] = |
| bool((data.mask[0] >> EI_DEVICE_ERRORS) & 0x01); |
| result["GPIO spoofing error injection supported"] = |
| bool((data.mask[0] >> EI_GPIO_SPOOFING) & 0x01); |
| nsmtool::helper::DisplayInJson(result); |
| } |
| }; |
| |
| class SetErrorInjectionPayload : public CommandInterface |
| { |
| public: |
| ~SetErrorInjectionPayload() = default; |
| SetErrorInjectionPayload() = delete; |
| SetErrorInjectionPayload(const SetErrorInjectionPayload&) = delete; |
| SetErrorInjectionPayload(SetErrorInjectionPayload&&) = default; |
| SetErrorInjectionPayload& |
| operator=(const SetErrorInjectionPayload&) = delete; |
| SetErrorInjectionPayload& operator=(SetErrorInjectionPayload&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetErrorInjectionPayload(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| app->add_option("-t,--errorInjectionType", errorInjectionType, |
| "Error Injection Type [Options: \n" |
| " 0x00: Memory Errors\n" |
| " 0x01: PCIe Errors\n" |
| " 0x02: Nvlink Errors\n" |
| " 0x03: Thermal Errors\n" |
| " 0x04: Device Errors\n" |
| " 0x05: GPIO Spoofing]"); |
| app->add_option("-s,--errorInjectionSubtype", errorInjectionSubtype, |
| "Error Injection Subtype [For Device errors Options: \n" |
| " 0x00: Fatal Error (if not applicable, use 0x00)\n" |
| " 0x01: Port Recovery Error\n" |
| " 0x02: USB Emulation Error\n" |
| " 0x03: Leak Detect Error]"); |
| app->add_option( |
| "-d,--data", rawData, |
| "Data for payload after error injection type and subtype") |
| ->required() |
| ->expected(-3); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| if (errorInjectionType == EI_DEVICE_ERRORS) |
| { |
| rawData.insert(rawData.begin(), 2, 0); |
| *reinterpret_cast<uint16_t*>(rawData.data()) = |
| errorInjectionSubtype; |
| } |
| |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_set_error_injection_payload_req) - |
| sizeof(uint8_t) + rawData.size()); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_error_injection_payload_req( |
| instanceId, rawData.data(), rawData.size(), errorInjectionType, |
| errorInjectionSubtype, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_set_error_injection_payload_resp( |
| responsePtr, payloadLength, &cc, &reason_code); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + sizeof(nsm_common_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| std::vector<uint8_t> rawData; |
| uint16_t errorInjectionType{}; |
| uint16_t errorInjectionSubtype{}; |
| }; |
| |
| class GetErrorInjectionPayload : public CommandInterface |
| { |
| public: |
| ~GetErrorInjectionPayload() = default; |
| GetErrorInjectionPayload() = delete; |
| GetErrorInjectionPayload(const GetErrorInjectionPayload&) = delete; |
| GetErrorInjectionPayload(GetErrorInjectionPayload&&) = default; |
| GetErrorInjectionPayload& |
| operator=(const GetErrorInjectionPayload&) = delete; |
| GetErrorInjectionPayload& operator=(GetErrorInjectionPayload&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetErrorInjectionPayload(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| app->add_option("-t,--errorInjectionType", errorInjectionType, |
| "Error Injection Type [Options: \n" |
| " 0x00: Memory Errors\n" |
| " 0x01: PCIe Errors\n" |
| " 0x02: Nvlink Errors\n" |
| " 0x03: Thermal Errors\n" |
| " 0x04: Device Errors\n" |
| " 0x05: GPIO Spoofing]"); |
| app->add_option("-s,--errorInjectionSubtype", errorInjectionSubtype, |
| "Error Injection Subtype [For Device errors Options: \n" |
| " 0x00: Fatal Error (if not applicable, use 0x00)\n" |
| " 0x01: Port Recovery Error\n" |
| " 0x02: USB Emulation Error\n" |
| " 0x03: Leak Detect Error]"); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_error_injection_payload_req)); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_error_injection_payload_req( |
| instanceId, errorInjectionType, errorInjectionSubtype, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| // Allocate buffer large enough for sensors data |
| std::vector<uint8_t> data(payloadLength, 0); |
| size_t dataSize = 0; |
| |
| auto rc = decode_get_error_injection_payload_resp( |
| responsePtr, payloadLength, errorInjectionType, |
| errorInjectionSubtype, &cc, &reason_code, data.data(), &dataSize); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + sizeof(nsm_common_resp)); |
| |
| return; |
| } |
| ordered_json result; |
| // resize sensorsData as per datasize |
| data.resize(dataSize); |
| result["Completion Code"] = cc; |
| result["Error Injection Type"] = errorInjectionType; |
| result["Error Injection Subtype"] = errorInjectionSubtype; |
| |
| // For device errors (type 4), skip first 2 bytes which represent |
| // the error injection subtype already displayed above |
| if (errorInjectionType == EI_DEVICE_ERRORS && data.size() >= 2) |
| { |
| std::vector<uint8_t> faultPayload(data.begin() + 2, data.end()); |
| result["Fault payload"] = faultPayload; |
| } |
| else |
| { |
| result["Fault payload"] = data; |
| } |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| uint16_t errorInjectionType{}; |
| uint16_t errorInjectionSubtype{}; |
| }; |
| |
| class ActivateErrorInjectionPayload : public CommandInterface |
| { |
| public: |
| ~ActivateErrorInjectionPayload() = default; |
| ActivateErrorInjectionPayload() = delete; |
| ActivateErrorInjectionPayload(const ActivateErrorInjectionPayload&) = |
| delete; |
| ActivateErrorInjectionPayload(ActivateErrorInjectionPayload&&) = default; |
| ActivateErrorInjectionPayload& |
| operator=(const ActivateErrorInjectionPayload&) = delete; |
| ActivateErrorInjectionPayload& |
| operator=(ActivateErrorInjectionPayload&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit ActivateErrorInjectionPayload(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| app->add_option("-t,--errorInjectionType", errorInjectionType, |
| "Error Injection Type [Options: \n" |
| " 0x00: Memory Errors\n" |
| " 0x01: PCIe Errors\n" |
| " 0x02: Nvlink Errors\n" |
| " 0x03: Thermal Errors\n" |
| " 0x04: Device Errors\n" |
| " 0x05: GPIO Spoofing]"); |
| app->add_option("-s,--errorInjectionSubtype", errorInjectionSubtype, |
| "Error Injection Subtype [For Device errors Options: \n" |
| " 0x00: Fatal Error (if not applicable, use 0x00)\n" |
| " 0x01: Port Recovery Error\n" |
| " 0x02: USB Emulation Error\n" |
| " 0x03: Leak Detect Error]"); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + |
| sizeof(nsm_activate_error_injection_payload_req)); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_activate_error_injection_payload_req( |
| instanceId, errorInjectionType, errorInjectionSubtype, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_activate_error_injection_payload_resp( |
| responsePtr, payloadLength, &cc, &reason_code); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + sizeof(nsm_common_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["Error Injection Type"] = errorInjectionType; |
| result["Error Injection Subtype"] = errorInjectionSubtype; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| uint16_t errorInjectionType{}; |
| uint16_t errorInjectionSubtype{}; |
| }; |
| |
| class SetCurrentErrorInjectionTypesV1 : public CommandInterface |
| { |
| public: |
| ~SetCurrentErrorInjectionTypesV1() = default; |
| SetCurrentErrorInjectionTypesV1() = delete; |
| SetCurrentErrorInjectionTypesV1(const SetCurrentErrorInjectionTypesV1&) = |
| delete; |
| SetCurrentErrorInjectionTypesV1(SetCurrentErrorInjectionTypesV1&&) = |
| default; |
| SetCurrentErrorInjectionTypesV1& |
| operator=(const SetCurrentErrorInjectionTypesV1&) = delete; |
| SetCurrentErrorInjectionTypesV1& |
| operator=(SetCurrentErrorInjectionTypesV1&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetCurrentErrorInjectionTypesV1(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| app->add_option("-d,--data", rawData, "raw data") |
| ->required() |
| ->expected(-3); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + |
| sizeof(nsm_set_error_injection_types_mask_req)); |
| nsm_error_injection_types_mask data; |
| for (size_t i = 0; i < 8 && i < rawData.size(); i++) |
| { |
| data.mask[i] = rawData[i]; |
| } |
| |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_current_error_injection_types_v1_req( |
| instanceId, &data, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_set_current_error_injection_types_v1_resp( |
| responsePtr, payloadLength, &cc, &reason_code); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + sizeof(nsm_common_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| std::vector<uint8_t> rawData; |
| }; |
| |
| class GetCurrentErrorInjectionTypesV1 : public CommandInterface |
| { |
| public: |
| ~GetCurrentErrorInjectionTypesV1() = default; |
| GetCurrentErrorInjectionTypesV1() = delete; |
| GetCurrentErrorInjectionTypesV1(const GetCurrentErrorInjectionTypesV1&) = |
| delete; |
| GetCurrentErrorInjectionTypesV1(GetCurrentErrorInjectionTypesV1&&) = |
| default; |
| GetCurrentErrorInjectionTypesV1& |
| operator=(const GetCurrentErrorInjectionTypesV1&) = delete; |
| GetCurrentErrorInjectionTypesV1& |
| operator=(GetCurrentErrorInjectionTypesV1&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetCurrentErrorInjectionTypesV1(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| {} |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_current_error_injection_types_v1_req(instanceId, |
| request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| nsm_error_injection_types_mask data; |
| |
| auto rc = decode_get_error_injection_types_v1_resp( |
| responsePtr, payloadLength, &cc, &reason_code, &data); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_error_injection_types_mask_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["DRAM and SRAM errors injection enabled"] = |
| bool((data.mask[0] >> EI_MEMORY_ERRORS) & 0x01); |
| result["PCI link error injection enabled"] = |
| bool((data.mask[0] >> EI_PCI_ERRORS) & 0x01); |
| result["Link error injection enabled"] = |
| bool((data.mask[0] >> EI_NVLINK_ERRORS) & 0x01); |
| result["Thermal error injection enabled"] = |
| bool((data.mask[0] >> EI_THERMAL_ERRORS) & 0x01); |
| result["Device error injection enabled"] = |
| bool((data.mask[0] >> EI_DEVICE_ERRORS) & 0x01); |
| result["GPIO spoofing error injection enabled"] = |
| bool((data.mask[0] >> EI_GPIO_SPOOFING) & 0x01); |
| nsmtool::helper::DisplayInJson(result); |
| } |
| }; |
| |
| class EnableDisableGpuIstMode : public CommandInterface |
| { |
| public: |
| ~EnableDisableGpuIstMode() = default; |
| EnableDisableGpuIstMode() = delete; |
| EnableDisableGpuIstMode(const EnableDisableGpuIstMode&) = delete; |
| EnableDisableGpuIstMode(EnableDisableGpuIstMode&&) = default; |
| EnableDisableGpuIstMode& operator=(const EnableDisableGpuIstMode&) = delete; |
| EnableDisableGpuIstMode& operator=(EnableDisableGpuIstMode&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit EnableDisableGpuIstMode(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| auto istModeGroup = app->add_option_group( |
| "Required", |
| "Device Index and Value for which GPU IST Mode will be set."); |
| |
| deviceIndex = 0; |
| istModeGroup->add_option( |
| "-d, --deviceIndex", deviceIndex, |
| "Device GPU IST Mode: 0-7: select GPU, 10 all GPUs"); |
| value = 0; |
| istModeGroup->add_option("-V, --value", value, |
| "Disable - 0 / Enable - 1"); |
| istModeGroup->require_option(2); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_enable_disable_gpu_ist_mode_req)); |
| int rc = NSM_SW_ERROR; |
| if (deviceIndex < 8 || deviceIndex == ALL_GPUS_DEVICE_INDEX) |
| { |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| rc = encode_enable_disable_gpu_ist_mode_req(instanceId, deviceIndex, |
| value, request); |
| } |
| else |
| { |
| std::cerr << "Invalid Device Index \n"; |
| } |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_enable_disable_gpu_ist_mode_resp( |
| responsePtr, payloadLength, &cc, &reason_code); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + sizeof(nsm_common_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| uint8_t deviceIndex; |
| uint8_t value; |
| }; |
| class GetFpgaDiagnosticsSettings : public CommandInterface |
| { |
| public: |
| ~GetFpgaDiagnosticsSettings() = default; |
| GetFpgaDiagnosticsSettings() = delete; |
| GetFpgaDiagnosticsSettings(const GetFpgaDiagnosticsSettings&) = delete; |
| GetFpgaDiagnosticsSettings(GetFpgaDiagnosticsSettings&&) = default; |
| GetFpgaDiagnosticsSettings& |
| operator=(const GetFpgaDiagnosticsSettings&) = delete; |
| GetFpgaDiagnosticsSettings& |
| operator=(GetFpgaDiagnosticsSettings&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetFpgaDiagnosticsSettings(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| auto fpgaDiagnosticsSettingsGroup = app->add_option_group( |
| "Required", "Data Index for which data source is to be retrieved."); |
| |
| dataId = 0; |
| fpgaDiagnosticsSettingsGroup->add_option( |
| "-d, --dataId", dataId, |
| "retrieve data source for dataId\n" |
| " 0 – Get WP Settings\n" |
| " 1 – Get PCIe Fundamental Reset State\n" |
| " 2 – Get WP Jumper Presence\n" |
| " 3 – Get GPU Degrade Mode Settings\n" |
| " 4 – Get GPU IST Mode Settings\n" |
| " 5 – Get Power Supply Status\n" |
| " 6 – Get Board Power Supply Status\n" |
| " 7 – Get Power Brake State\n" |
| " 8 – Get Thermal Alert State\n" |
| " 9 – Get NVSW Flash Present Settings\n" |
| " 10 – Get NVSW Fuse SRC Settings\n" |
| " 11 – Get Retimer LTSSM Dump Mode Settings\n" |
| " 12 – Get GPU Presence\n" |
| " 13 – Get GPU Power Status\n" |
| "255 – Get Aggregate Telemetry\n"); |
| fpgaDiagnosticsSettingsGroup->require_option(1); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_fpga_diagnostics_settings_req)); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_fpga_diagnostics_settings_req( |
| instanceId, (fpga_diagnostics_settings_data_index)dataId, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| switch ((fpga_diagnostics_settings_data_index)dataId) |
| { |
| case GET_WP_SETTINGS: |
| { |
| nsm_fpga_diagnostics_settings_wp data; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_get_fpga_diagnostics_settings_wp_resp( |
| responsePtr, payloadLength, &cc, &reason_code, &data); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr |
| << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_fpga_diagnostics_settings_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["Any NVSW EROT"] = (int)data.nvSwitch; |
| result["NVSW 1"] = (int)data.nvSwitch1; |
| result["NVSW 2"] = (int)data.nvSwitch2; |
| result["PEXSW EROT"] = (int)data.pex; |
| result["FRU EEPROM (Baseboard or CX7 or HMC)"] = |
| (int)data.baseboard; |
| result["HMC SPI Flash"] = (int)data.hmc; |
| result["Any Retimer"] = (int)data.retimer; |
| result["Retimer 1"] = (int)data.retimer1; |
| result["Retimer 2"] = (int)data.retimer2; |
| result["Retimer 3"] = (int)data.retimer3; |
| result["Retimer 4"] = (int)data.retimer4; |
| result["Retimer 5"] = (int)data.retimer5; |
| result["Retimer 6"] = (int)data.retimer6; |
| result["Retimer 7"] = (int)data.retimer7; |
| result["Retimer 8"] = (int)data.retimer8; |
| result["GPUs 1-4 SPI Flash"] = (int)data.gpu1_4; |
| result["GPUs 5-8 SPI Flash"] = (int)data.gpu5_8; |
| result["GPUs SPI Flash"] = (int)(data.gpu1_4 && data.gpu5_8 && |
| data.gpu9_12 && data.gpu13_16); |
| result["CX8 SPI Flash"] = (int)data.cx8; |
| result["GPU 1"] = (int)data.gpu1; |
| result["GPU 2"] = (int)data.gpu2; |
| result["GPU 3"] = (int)data.gpu3; |
| result["GPU 4"] = (int)data.gpu4; |
| result["GPU 5"] = (int)data.gpu5; |
| result["GPU 6"] = (int)data.gpu6; |
| result["GPU 7"] = (int)data.gpu7; |
| result["GPU 8"] = (int)data.gpu8; |
| result["GPU 9"] = (int)data.gpu9; |
| result["GPU 10"] = (int)data.gpu10; |
| result["GPU 11"] = (int)data.gpu11; |
| result["GPU 12"] = (int)data.gpu12; |
| result["GPU 13"] = (int)data.gpu13; |
| result["GPU 14"] = (int)data.gpu14; |
| result["GPU 15"] = (int)data.gpu15; |
| result["GPU 16"] = (int)data.gpu16; |
| result["CPU 1"] = (int)data.cpu1; |
| result["CPU 2"] = (int)data.cpu2; |
| result["CPU 3"] = (int)data.cpu3; |
| result["CPU 4"] = (int)data.cpu4; |
| |
| nsmtool::helper::DisplayInJson(result); |
| break; |
| } |
| case GET_WP_JUMPER_PRESENCE: |
| { |
| nsm_fpga_diagnostics_settings_wp_jumper data; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_get_fpga_diagnostics_settings_wp_jumper_resp( |
| responsePtr, payloadLength, &cc, &reason_code, &data); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr |
| << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_fpga_diagnostics_settings_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["WP Presence"] = (int)data.presence; |
| nsmtool::helper::DisplayInJson(result); |
| break; |
| } |
| case GET_POWER_SUPPLY_STATUS: |
| { |
| uint8_t data; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_get_power_supply_status_resp( |
| responsePtr, payloadLength, &cc, &reason_code, &data); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_power_supply_status_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["Power supply status"] = (int)data; |
| nsmtool::helper::DisplayInJson(result); |
| break; |
| } |
| case GET_GPU_PRESENCE: |
| { |
| uint8_t data; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_get_gpu_presence_resp( |
| responsePtr, payloadLength, &cc, &reason_code, &data); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_gpu_presence_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["GPUs presence"] = (int)data; |
| nsmtool::helper::DisplayInJson(result); |
| break; |
| } |
| case GET_GPU_POWER_STATUS: |
| { |
| uint8_t data; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_get_gpu_power_status_resp( |
| responsePtr, payloadLength, &cc, &reason_code, &data); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_gpu_power_status_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["GPUs power status"] = (int)data; |
| nsmtool::helper::DisplayInJson(result); |
| break; |
| } |
| case GET_GPU_IST_MODE_SETTINGS: |
| { |
| uint8_t data; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_get_gpu_ist_mode_resp( |
| responsePtr, payloadLength, &cc, &reason_code, &data); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_gpu_ist_mode_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["GPUs IST Mode Settings"] = (int)data; |
| nsmtool::helper::DisplayInJson(result); |
| break; |
| } |
| default: |
| { |
| std::cerr << "Invalid Data Id \n"; |
| break; |
| } |
| } |
| } |
| |
| private: |
| uint8_t dataId; |
| }; |
| |
| const std::map<int, std::string> settingsDictionary = {{ |
| {RP_IN_SYSTEM_TEST, "In system test"}, |
| {RP_FUSING_MODE, "Fusing Mode"}, |
| {RP_CONFIDENTIAL_COMPUTE, "Confidential compute"}, |
| {RP_BAR0_FIREWALL, "BAR0 Firewall"}, |
| {RP_CONFIDENTIAL_COMPUTE_DEV_MODE, "Confidential compute dev-mode"}, |
| {RP_TOTAL_GPU_POWER_CURRENT_LIMIT, "Total GPU Power (TGP) current limit"}, |
| {RP_TOTAL_GPU_POWER_RATED_LIMIT, "Total GPU Power (TGP) rated limit"}, |
| {RP_TOTAL_GPU_POWER_MAX_LIMIT, "Total GPU Power (TGP) max limit"}, |
| {RP_TOTAL_GPU_POWER_MIN_LIMIT, "Total GPU Power (TGP) min limit"}, |
| {RP_CLOCK_LIMIT, "Clock limit"}, |
| {RP_NVLINK_DISABLE, "NVLink disable"}, |
| {RP_ECC_ENABLE, "ECC enable"}, |
| {RP_PCIE_VF_CONFIGURATION, "PCIe VF configuration"}, |
| {RP_ROW_REMAPPING_ALLOWED, "Row remapping allowed"}, |
| {RP_ROW_REMAPPING_FEATURE, "Row remapping feature"}, |
| {RP_HBM_FREQUENCY_CHANGE, "HBM frequency change"}, |
| {RP_HULK_LICENSE_UPDATE, "HULK license update"}, |
| {RP_FORCE_TEST_COUPLING, "Force test coupling"}, |
| {RP_BAR0_TYPE_CONFIG, "BAR0 type config"}, |
| {RP_EDPP_SCALING_FACTOR, "EDPp scaling factor"}, |
| {RP_POWER_SMOOTHING_PRIVILEGE_LEVEL_1, "Power Smoothing Privilege Level 1"}, |
| {RP_POWER_SMOOTHING_PRIVILEGE_LEVEL_2, "Power Smoothing Privilege Level 2"}, |
| {RP_EGM_MODE, "Extend GPU Memory Mode"}, |
| {RP_INFOROM_RECREATE_ALLOW_INB, "InfoROM filesystem recreate"}, |
| {RP_RUNTIME_IN_SYSTEM_TEST, "Runtime in system test"}, |
| {RP_DUAL_PART_NUMBERS, "AdaptiveTGPMode (Dual Part Number)"}, |
| }}; |
| class GetReconfigurationPermissionsV1 : public CommandInterface |
| { |
| public: |
| ~GetReconfigurationPermissionsV1() = default; |
| GetReconfigurationPermissionsV1() = delete; |
| GetReconfigurationPermissionsV1(const GetReconfigurationPermissionsV1&) = |
| delete; |
| GetReconfigurationPermissionsV1(GetReconfigurationPermissionsV1&&) = |
| default; |
| GetReconfigurationPermissionsV1& |
| operator=(const GetReconfigurationPermissionsV1&) = delete; |
| GetReconfigurationPermissionsV1& |
| operator=(GetReconfigurationPermissionsV1&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetReconfigurationPermissionsV1(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app), settingIndex(-1) |
| { |
| auto getReconfigurationPermissionsV1Group = app->add_option_group( |
| "Required", |
| "Setting Index for which data source is to be retrieved."); |
| std::string list; |
| for (auto [id, setting] : settingsDictionary) |
| { |
| list += std::to_string((int)id) + " - " + setting + "\n"; |
| } |
| getReconfigurationPermissionsV1Group->add_option( |
| "-s, --settingId", settingIndex, |
| "retrieve data source for settingIndex\n" + list); |
| getReconfigurationPermissionsV1Group->require_option(1); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_reconfiguration_permissions_v1_req)); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_reconfiguration_permissions_v1_req( |
| instanceId, (reconfiguration_permissions_v1_index)settingIndex, |
| request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| if (settingsDictionary.find(settingIndex) == settingsDictionary.end()) |
| { |
| std::cerr << "Invalid Settings Id \n"; |
| return; |
| } |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| nsm_reconfiguration_permissions_v1 data; |
| |
| auto rc = decode_get_reconfiguration_permissions_v1_resp( |
| responsePtr, payloadLength, &cc, &reason_code, &data); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_reconfiguration_permissions_v1_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["PRC Knob"] = settingsDictionary.at(settingIndex); |
| result["Oneshot (Host)"] = bool(data.host_oneshot); |
| result["Persistent (Host)"] = bool(data.host_persistent); |
| result["FLR_Persistent (Host)"] = bool(data.host_flr_persistent); |
| result["Oneshot (DOE)"] = bool(data.DOE_oneshot); |
| result["Persistent (DOE)"] = bool(data.DOE_persistent); |
| result["FLR_Persistent (DOE)"] = bool(data.DOE_flr_persistent); |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| int settingIndex; |
| }; |
| |
| class SetReconfigurationPermissionsV1 : public CommandInterface |
| { |
| public: |
| ~SetReconfigurationPermissionsV1() = default; |
| SetReconfigurationPermissionsV1() = delete; |
| SetReconfigurationPermissionsV1(const SetReconfigurationPermissionsV1&) = |
| delete; |
| SetReconfigurationPermissionsV1(SetReconfigurationPermissionsV1&&) = |
| default; |
| SetReconfigurationPermissionsV1& |
| operator=(const SetReconfigurationPermissionsV1&) = delete; |
| SetReconfigurationPermissionsV1& |
| operator=(SetReconfigurationPermissionsV1&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetReconfigurationPermissionsV1(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app), settingIndex(-1), configuration(-1), |
| permission() |
| { |
| std::string settingsList; |
| for (auto [id, setting] : settingsDictionary) |
| { |
| settingsList += std::to_string((int)id) + " - " + setting + "\n"; |
| } |
| std::string configsList; |
| const std::map<reconfiguration_permissions_v1_setting, std::string> |
| configurationsDictionary = { |
| {RP_ONESHOOT_HOT_RESET, "Oneshot (hot reset)"}, |
| {RP_PERSISTENT, "Persistent"}, |
| {RP_ONESHOT_FLR, "Oneshot (FLR)"}, |
| }; |
| for (auto [id, config] : configurationsDictionary) |
| { |
| configsList += std::to_string((int)id) + " - " + config + "\n"; |
| } |
| |
| auto setReconfigurationPermissionsV1Group = app->add_option_group( |
| "Required", |
| "Setting Index, Configuration and Permission for which data source is to be retrieved."); |
| setReconfigurationPermissionsV1Group->add_option( |
| "-s, --settingId", settingIndex, |
| "retrieve data source for settingIndex\n" + settingsList); |
| setReconfigurationPermissionsV1Group->add_option( |
| "-c, --configuration", configuration, |
| "retrieve data source for configuration\n" + configsList); |
| setReconfigurationPermissionsV1Group->add_option( |
| "-V, --value", permission, |
| "retrieve data source for permission value - \n0 - DISALLOW_HOST_DISALLOW_DOE \n1 - ALLOW_HOST_DISALLOW_DOE \n2 - DISALLOW_HOST_ALLOW_DOE \n3 - ALLOW_HOST_ALLOW_DOE\n"); |
| setReconfigurationPermissionsV1Group->require_option(3); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + |
| sizeof(nsm_set_reconfiguration_permissions_v1_req)); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_reconfiguration_permissions_v1_req( |
| instanceId, (reconfiguration_permissions_v1_index)settingIndex, |
| (reconfiguration_permissions_v1_setting)configuration, permission, |
| request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| if (settingsDictionary.find(settingIndex) == settingsDictionary.end()) |
| { |
| std::cerr << "Invalid Settings Id \n"; |
| return; |
| } |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_set_reconfiguration_permissions_v1_resp( |
| responsePtr, payloadLength, &cc, &reason_code); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_reconfiguration_permissions_v1_resp)); |
| |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| int settingIndex; |
| int configuration; |
| uint8_t permission; |
| }; |
| |
| class GetConfidentialComputeModeV1 : public CommandInterface |
| { |
| public: |
| ~GetConfidentialComputeModeV1() = default; |
| GetConfidentialComputeModeV1() = delete; |
| GetConfidentialComputeModeV1(const GetConfidentialComputeModeV1&) = delete; |
| GetConfidentialComputeModeV1(GetConfidentialComputeModeV1&&) = default; |
| GetConfidentialComputeModeV1& |
| operator=(const GetConfidentialComputeModeV1&) = delete; |
| GetConfidentialComputeModeV1& |
| operator=(GetConfidentialComputeModeV1&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_confidential_compute_mode_v1_req(instanceId, |
| request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| uint16_t data_size; |
| uint8_t current_mode; |
| uint8_t pending_mode; |
| auto rc = decode_get_confidential_compute_mode_v1_resp( |
| responsePtr, payloadLength, &cc, &data_size, &reason_code, |
| ¤t_mode, &pending_mode); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_confidential_compute_mode_v1_resp)); |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["Current Mode"] = current_mode; |
| result["Pending Mode"] = pending_mode; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| }; |
| |
| class SetConfidentialComputeModeV1 : public CommandInterface |
| { |
| public: |
| ~SetConfidentialComputeModeV1() = default; |
| SetConfidentialComputeModeV1() = delete; |
| SetConfidentialComputeModeV1(const SetConfidentialComputeModeV1&) = delete; |
| SetConfidentialComputeModeV1(SetConfidentialComputeModeV1&&) = default; |
| SetConfidentialComputeModeV1& |
| operator=(const SetConfidentialComputeModeV1&) = delete; |
| SetConfidentialComputeModeV1& |
| operator=(SetConfidentialComputeModeV1&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetConfidentialComputeModeV1(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| auto setConfidentialComputeModeV1 = |
| app->add_option_group("Required", "Set Confidential Compute Mode"); |
| setConfidentialComputeModeV1->add_option("-r, --mode", mode, "mode"); |
| setConfidentialComputeModeV1->require_option(1); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + |
| sizeof(nsm_set_confidential_compute_mode_v1_req)); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_confidential_compute_mode_v1_req(instanceId, mode, |
| request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| uint16_t data_size; |
| auto rc = decode_set_confidential_compute_mode_v1_resp( |
| responsePtr, payloadLength, &cc, &data_size, &reason_code); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + sizeof(nsm_common_resp)); |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = cc; // check in nsm spec before merging |
| // code and do required change |
| |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| uint8_t mode; |
| }; |
| |
| class SetDevicemodeSettings : public CommandInterface |
| { |
| public: |
| ~SetDevicemodeSettings() = default; |
| SetDevicemodeSettings() = delete; |
| SetDevicemodeSettings(const SetDevicemodeSettings&) = delete; |
| SetDevicemodeSettings(SetDevicemodeSettings&&) = default; |
| SetDevicemodeSettings& operator=(const SetDevicemodeSettings&) = delete; |
| SetDevicemodeSettings& operator=(SetDevicemodeSettings&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetDevicemodeSettings(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app), device_mode_index(0), |
| l1_prediction_mode(nsm_l1_prediction_mode_config::DISABLED) |
| { |
| auto setNetworkInterfaceMode = |
| app->add_option_group("Required", "Set Network Interface Mode"); |
| setNetworkInterfaceMode->add_option("-i, --index", device_mode_index, |
| "device_mode_index"); |
| setNetworkInterfaceMode->add_option("-M, --mode", l1_prediction_mode, |
| "l1_prediction_mode\n" |
| "1 - Enable\n" |
| "0 - Disable"); |
| setNetworkInterfaceMode->require_option(2); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_set_device_mode_setting_req), 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_device_mode_setting_req( |
| instanceId, device_mode_index, l1_prediction_mode, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = decode_set_device_mode_setting_resp( |
| responsePtr, payloadLength, &cc, &reason_code); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << (int)cc |
| << ", reasonCode=" << (int)reason_code << "\n" |
| << payloadLength << "...." |
| << (sizeof(nsm_msg_hdr) + sizeof(nsm_common_resp)); |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["Reason Code"] = reason_code; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| uint8_t device_mode_index; |
| enum nsm_l1_prediction_mode_config l1_prediction_mode; |
| }; |
| |
| class GetDevicemodeSettings : public CommandInterface |
| { |
| public: |
| ~GetDevicemodeSettings() = default; |
| GetDevicemodeSettings() = delete; |
| GetDevicemodeSettings(const GetDevicemodeSettings&) = delete; |
| GetDevicemodeSettings(GetDevicemodeSettings&&) = default; |
| GetDevicemodeSettings& operator=(const GetDevicemodeSettings&) = delete; |
| GetDevicemodeSettings& operator=(GetDevicemodeSettings&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetDevicemodeSettings(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| mode_index = 0; |
| auto getNetworkInterfaceMode = |
| app->add_option_group("Required", "Get Network Interface Mode"); |
| getNetworkInterfaceMode->add_option("-r, --mode_index", mode_index, |
| "mode_index"); |
| getNetworkInterfaceMode->require_option(1); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_device_mode_setting_req), 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_device_mode_setting_req(instanceId, mode_index, |
| request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| enum nsm_l1_prediction_mode_config device_mode; |
| |
| auto rc = decode_get_device_mode_setting_resp( |
| responsePtr, payloadLength, &cc, &reason_code, &device_mode); |
| |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reason_code) |
| << "\n" |
| << payloadLength << "...." |
| << (sizeof(struct nsm_msg_hdr) + |
| sizeof(struct nsm_get_device_mode_setting_resp)); |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["Device Mode"] = static_cast<int>(device_mode); |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| uint8_t mode_index; |
| }; |
| |
| class GetDeviceModeSettingsV2 : public CommandInterface |
| { |
| public: |
| ~GetDeviceModeSettingsV2() = default; |
| GetDeviceModeSettingsV2() = delete; |
| GetDeviceModeSettingsV2(const GetDeviceModeSettingsV2&) = delete; |
| GetDeviceModeSettingsV2(GetDeviceModeSettingsV2&&) = default; |
| GetDeviceModeSettingsV2& operator=(const GetDeviceModeSettingsV2&) = delete; |
| GetDeviceModeSettingsV2& operator=(GetDeviceModeSettingsV2&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetDeviceModeSettingsV2(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| auto getDeviceModeSettingsV2Group = |
| app->add_option_group("Required", "Get Device Mode Settings v2"); |
| getDeviceModeSettingsV2Group->add_option( |
| "-i, --deviceModeIndex", deviceModeIndex, |
| "Device mode index (NvU32)\n" |
| " 3 - DPU Operation Mode (1 byte: 0=DPU, 1=NIC)\n" |
| " 4 - PCIe Device Mode (3 bytes: multi-socket, EW, bifurcation)\n" |
| " value encodes sub-modes in LE byte order:\n" |
| " byte[0]=multi-socket byte[1]=controlledEW byte[2]=bifurcation\n" |
| " 7 - Max AC Power Ramp Rate Config (NvU32, Watts/sec)\n" |
| " 8 - SoC Power Smoothing Enabled (NvBool)\n" |
| " 9 - SoC Power Smoothing Preset Index (NvU8)\n" |
| " 10 - SoC Power Brake Enabled (NvBool)\n" |
| " 11 - One Shot GPU Base Power Limit\n" |
| " 12 - Persistent GPU Base Power Limit\n" |
| " 13 - One Shot CPU Power Limit GPU Copy\n" |
| " 14 - Persistent CPU Power Limit GPU Copy\n" |
| " 15 - One Shot GPU Copy Switch Power Limit\n" |
| " 16 - Persistent GPU Copy Switch Power Limit\n" |
| " 21 - AdaptiveTGPMode / Dual Part Number (NvBool)"); |
| getDeviceModeSettingsV2Group->require_option(1); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_device_mode_settings_v2_req), |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_device_mode_settings_v2_req( |
| instanceId, deviceModeIndex, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| uint8_t currentModeData[256]; |
| uint16_t currentModeLength = 0; |
| uint8_t pendingModeData[256]; |
| uint16_t pendingModeLength = 0; |
| |
| auto rc = decode_get_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode, currentModeData, |
| ¤tModeLength, pendingModeData, &pendingModeLength); |
| |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["Current Mode Length"] = currentModeLength; |
| |
| if (currentModeLength == sizeof(uint32_t)) |
| { |
| uint32_t currentValue; |
| memcpy(¤tValue, currentModeData, sizeof(uint32_t)); |
| currentValue = le32toh(currentValue); |
| result["Current Mode Value"] = currentValue; |
| } |
| else if (currentModeLength > 0) |
| { |
| std::vector<uint8_t> currentData( |
| currentModeData, currentModeData + currentModeLength); |
| result["Current Mode Data"] = currentData; |
| } |
| |
| result["Pending Mode Length"] = pendingModeLength; |
| if (pendingModeLength == sizeof(uint32_t)) |
| { |
| uint32_t pendingValue; |
| memcpy(&pendingValue, pendingModeData, sizeof(uint32_t)); |
| pendingValue = le32toh(pendingValue); |
| result["Pending Mode Value"] = pendingValue; |
| } |
| else if (pendingModeLength > 0) |
| { |
| std::vector<uint8_t> pendingData( |
| pendingModeData, pendingModeData + pendingModeLength); |
| result["Pending Mode Data"] = pendingData; |
| } |
| |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| uint32_t deviceModeIndex = 0; |
| }; |
| |
| class SetDeviceModeSettingsV2 : public CommandInterface |
| { |
| public: |
| ~SetDeviceModeSettingsV2() = default; |
| SetDeviceModeSettingsV2() = delete; |
| SetDeviceModeSettingsV2(const SetDeviceModeSettingsV2&) = delete; |
| SetDeviceModeSettingsV2(SetDeviceModeSettingsV2&&) = default; |
| SetDeviceModeSettingsV2& operator=(const SetDeviceModeSettingsV2&) = delete; |
| SetDeviceModeSettingsV2& operator=(SetDeviceModeSettingsV2&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetDeviceModeSettingsV2(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| auto setDeviceModeSettingsV2Group = |
| app->add_option_group("Required", "Set Device Mode Settings v2"); |
| setDeviceModeSettingsV2Group->add_option( |
| "-i, --deviceModeIndex", deviceModeIndex, |
| "Device mode index (NvU32)\n" |
| " 3 - DPU Operation Mode (1 byte: 0=DPU, 1=NIC)\n" |
| " 4 - PCIe Device Mode (3 bytes: multi-socket, EW, bifurcation)\n" |
| " value encodes sub-modes in LE byte order:\n" |
| " byte[0]=multi-socket byte[1]=controlledEW byte[2]=bifurcation\n" |
| " 7 - Max AC Power Ramp Rate Config (NvU32, Watts/sec)\n" |
| " 8 - SoC Power Smoothing Enabled (NvBool)\n" |
| " 9 - SoC Power Smoothing Preset Index (NvU8)\n" |
| " 10 - SoC Power Brake Enabled (NvBool)\n" |
| " 11 - One Shot GPU Base Power Limit (NvU32)\n" |
| " 12 - Persistent GPU Base Power Limit (NvU32)\n" |
| " 13 - One Shot CPU Power Limit GPU Copy (NvU32)\n" |
| " 14 - Persistent CPU Power Limit GPU Copy (NvU32)\n" |
| " 21 - AdaptiveTGPMode / Dual Part Number (NvBool)"); |
| setDeviceModeSettingsV2Group->add_option("-l, --value", deviceModeValue, |
| "Device mode value (uint32)"); |
| setDeviceModeSettingsV2Group->add_option( |
| "-s, --size", deviceModeDataSize, |
| "Number of bytes of mode data to send (default: 4).\n" |
| "Must match the mode data length expected by the device\n" |
| "for the given device mode index (see NSM spec).\n" |
| "Only the first -s bytes of the LE value are sent.\n" |
| "Max: 4 bytes."); |
| setDeviceModeSettingsV2Group->require_option(2); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| uint8_t payload[sizeof(uint32_t)] = {0}; |
| uint16_t payloadLen = 0; |
| |
| switch (deviceModeIndex) |
| { |
| case DEVICE_MODE_SOC_POWER_SMOOTHING_ENABLED: |
| case DEVICE_MODE_SOC_POWER_SMOOTHING_PRESET_INDEX: |
| case DEVICE_MODE_SOC_POWER_BRAKE_ENABLED: |
| case DEVICE_MODE_ADAPTIVE_TGPMODE: |
| { |
| payload[0] = static_cast<uint8_t>( |
| static_cast<uint32_t>(deviceModeValue)); |
| payloadLen = sizeof(uint8_t); |
| break; |
| } |
| default: |
| { |
| uint16_t modeDataLen = |
| static_cast<uint16_t>(deviceModeDataSize); |
| if (modeDataLen > sizeof(uint32_t)) |
| { |
| std::cerr |
| << "Error: mode data size cannot exceed 4 bytes\n"; |
| return {NSM_SW_ERROR, {}}; |
| } |
| uint32_t valueLE = |
| htole32(static_cast<uint32_t>(deviceModeValue)); |
| memcpy(payload, &valueLE, sizeof(uint32_t)); |
| payloadLen = modeDataLen; |
| break; |
| } |
| } |
| |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_set_device_mode_settings_v2_req) + |
| payloadLen - 1, |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_device_mode_settings_v2_req( |
| instanceId, deviceModeIndex, payload, payloadLen, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| |
| auto rc = decode_set_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode); |
| |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: " |
| << "rc=" << rc << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| |
| ordered_json result; |
| result["Completion Code"] = cc; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| uint32_t deviceModeIndex = 0; |
| uint32_t deviceModeValue = 0; |
| uint32_t deviceModeDataSize = sizeof(uint32_t); |
| }; |
| |
| class SetDeviceConfig : public CommandInterface |
| { |
| public: |
| ~SetDeviceConfig() = default; |
| SetDeviceConfig() = delete; |
| SetDeviceConfig(const SetDeviceConfig&) = delete; |
| SetDeviceConfig(SetDeviceConfig&&) = default; |
| SetDeviceConfig& operator=(const SetDeviceConfig&) = delete; |
| SetDeviceConfig& operator=(SetDeviceConfig&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetDeviceConfig(const char* type, const char* name, |
| CLI::App* app) : CommandInterface(type, name, app) |
| { |
| auto g = app->add_option_group("Required", "Set Device Config (0x10)"); |
| g->add_option("-t,--type", typeStr, |
| "Device configuration type (decimal or 0x hex)"); |
| g->add_option( |
| "-d,--data-hex", dataHex, |
| "Configuration data as hex string (even length; total with 4-byte " |
| "type must fit uint16_t V2 data_size)"); |
| g->require_option(2); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> payload; |
| if (!parseHexToBytes(dataHex, payload)) |
| { |
| std::cerr << "Invalid --data-hex (use pairs of hex digits)\n"; |
| return {NSM_SW_ERROR_DATA, {}}; |
| } |
| if (payload.size() > static_cast<size_t>(UINT16_MAX) - sizeof(uint32_t)) |
| { |
| std::cerr << "Data plus 4-byte type exceeds uint16_t data_size\n"; |
| return {NSM_SW_ERROR_LENGTH, {}}; |
| } |
| char* endptr = nullptr; |
| unsigned long parsedType = std::strtoul(typeStr.c_str(), &endptr, 0); |
| if (endptr == typeStr.c_str() || *endptr != '\0') |
| { |
| std::cerr << "Invalid --type value\n"; |
| return {NSM_SW_ERROR_DATA, {}}; |
| } |
| uint32_t cfgType = static_cast<uint32_t>(parsedType); |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req_v2) + |
| sizeof(uint32_t) + payload.size(), |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| int rc = encode_set_device_config_v2_req( |
| instanceId, cfgType, payload.data(), |
| static_cast<uint16_t>(payload.size()), request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| auto rc = decode_set_device_config_v2_resp(responsePtr, payloadLength, |
| &cc, &reasonCode); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "SetDeviceConfig response error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << reasonCode << "\n"; |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = static_cast<int>(cc); |
| result["Command"] = "SetDeviceConfig (0x10)"; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| std::string typeStr; |
| std::string dataHex; |
| }; |
| |
| class GetDeviceConfig : public CommandInterface |
| { |
| public: |
| ~GetDeviceConfig() = default; |
| GetDeviceConfig() = delete; |
| GetDeviceConfig(const GetDeviceConfig&) = delete; |
| GetDeviceConfig(GetDeviceConfig&&) = default; |
| GetDeviceConfig& operator=(const GetDeviceConfig&) = delete; |
| GetDeviceConfig& operator=(GetDeviceConfig&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetDeviceConfig(const char* type, const char* name, |
| CLI::App* app) : CommandInterface(type, name, app) |
| { |
| auto g = app->add_option_group("Required", "Get Device Config (0x11)"); |
| g->add_option("-t,--type", typeStr, |
| "Device configuration type (decimal or 0x hex)"); |
| g->add_option( |
| "-q,--query-hex", queryHex, |
| "Optional query blob as hex (identifier fields per spec)"); |
| g->require_option(1); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> query; |
| if (!parseHexToBytes(queryHex, query)) |
| { |
| std::cerr << "Invalid --query-hex\n"; |
| return {NSM_SW_ERROR_DATA, {}}; |
| } |
| char* endptr = nullptr; |
| unsigned long parsedType = std::strtoul(typeStr.c_str(), &endptr, 0); |
| if (endptr == typeStr.c_str() || *endptr != '\0') |
| { |
| std::cerr << "Invalid --type value\n"; |
| return {NSM_SW_ERROR_DATA, {}}; |
| } |
| uint32_t cfgType = static_cast<uint32_t>(parsedType); |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req_v2) + |
| sizeof(uint32_t) + query.size(), |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| int rc = encode_get_device_config_v2_req( |
| instanceId, cfgType, query.data(), |
| static_cast<uint16_t>(query.size()), request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| std::vector<uint8_t> cur(static_cast<size_t>(UINT16_MAX)); |
| uint16_t curLen = 0; |
| std::vector<uint8_t> pend(static_cast<size_t>(UINT16_MAX)); |
| uint16_t pendLen = 0; |
| auto rc = decode_get_device_config_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode, cur.data(), &curLen, |
| pend.data(), &pendLen); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "GetDeviceConfig response error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << reasonCode << "\n"; |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = static_cast<int>(cc); |
| result["Command"] = "GetDeviceConfig (0x11)"; |
| result["Current Config Length"] = curLen; |
| result["Current Config Hex"] = bytesToHexString(cur.data(), curLen); |
| result["Pending Config Length"] = pendLen; |
| result["Pending Config Hex"] = bytesToHexString(pend.data(), pendLen); |
| if (curLen == sizeof(uint32_t)) |
| { |
| uint32_t v; |
| std::memcpy(&v, cur.data(), sizeof(v)); |
| result["Current Config As NvU32"] = le32toh(v); |
| } |
| if (pendLen == sizeof(uint32_t)) |
| { |
| uint32_t v; |
| std::memcpy(&v, pend.data(), sizeof(v)); |
| result["Pending Config As NvU32"] = le32toh(v); |
| } |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| std::string typeStr; |
| std::string queryHex; |
| }; |
| |
| /* OOB Miswiring Detection: convenience nsmtool |
| * subcommands targeting NSM Type 5 DEVICE_MODE_LLDP (index 24) LLDP mode |
| * bitfield on devices reporting NSM_DEV_ID_PCIE_BRIDGE via Type 0 |
| * GetDeviceIdentification. */ |
| class GetLLDPMode : public CommandInterface |
| { |
| public: |
| ~GetLLDPMode() = default; |
| GetLLDPMode() = delete; |
| GetLLDPMode(const GetLLDPMode&) = delete; |
| GetLLDPMode(GetLLDPMode&&) = default; |
| GetLLDPMode& operator=(const GetLLDPMode&) = delete; |
| GetLLDPMode& operator=(GetLLDPMode&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetLLDPMode(const char* type, const char* name, CLI::App* app) : |
| CommandInterface(type, name, app) |
| {} |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_device_mode_settings_v2_req), |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_device_mode_settings_v2_req( |
| instanceId, static_cast<uint32_t>(DEVICE_MODE_LLDP), request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| constexpr size_t maxModeBytes = 16; |
| uint8_t currentData[maxModeBytes] = {}; |
| uint8_t pendingData[maxModeBytes] = {}; |
| uint16_t currentLength = 0; |
| uint16_t pendingLength = 0; |
| |
| auto rc = decode_get_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode, currentData, |
| ¤tLength, pendingData, &pendingLength); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| if (currentLength != sizeof(nsm_lldp_mode_bitfield)) |
| { |
| std::cerr << "Invalid current-mode payload length " << currentLength |
| << " (expected 1 byte)\n"; |
| return; |
| } |
| struct nsm_lldp_mode_bitfield view = {}; |
| memcpy(&view, ¤tData[0], sizeof(view)); |
| ordered_json result; |
| result["TX Mode"] = static_cast<uint8_t>(view.tx_mode); |
| result["RX Mode"] = static_cast<uint8_t>(view.rx_mode); |
| result["DCBX Mode"] = static_cast<uint8_t>(view.dcbx_mode); |
| result["Raw Byte"] = currentData[0]; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| }; |
| |
| class SetLLDPMode : public CommandInterface |
| { |
| public: |
| ~SetLLDPMode() = default; |
| SetLLDPMode() = delete; |
| SetLLDPMode(const SetLLDPMode&) = delete; |
| SetLLDPMode(SetLLDPMode&&) = default; |
| SetLLDPMode& operator=(const SetLLDPMode&) = delete; |
| SetLLDPMode& operator=(SetLLDPMode&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetLLDPMode(const char* type, const char* name, CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| auto g = app->add_option_group( |
| "Required", |
| "Set LLDP Mode (NSM Type 5 idx 24): tx/rx 0=Off 1=Mandatory 2=All; dcbx 0=Disabled 1=Enabled"); |
| g->add_option("--tx", txMode, "TX mode (0/1/2)"); |
| g->add_option("--rx", rxMode, "RX mode (0/1/2)"); |
| g->add_option("--dcbx", dcbxMode, "DCBX mode (0/1)"); |
| g->require_option(3); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| if (txMode > NSM_LLDP_DIR_MODE_ALL || rxMode > NSM_LLDP_DIR_MODE_ALL || |
| dcbxMode > NSM_LLDP_DCBX_ENABLED) |
| { |
| std::cerr << "Invalid LLDP bitfield values\n"; |
| return {NSM_SW_ERROR_DATA, {}}; |
| } |
| struct nsm_lldp_mode_bitfield view = {}; |
| view.tx_mode = txMode; |
| view.rx_mode = rxMode; |
| view.dcbx_mode = dcbxMode; |
| uint8_t encoded = 0; |
| memcpy(&encoded, &view, sizeof(encoded)); |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_set_device_mode_settings_v2_req), |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_device_mode_settings_v2_req( |
| instanceId, static_cast<uint32_t>(DEVICE_MODE_LLDP), &encoded, |
| sizeof(encoded), request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| auto rc = decode_set_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = cc; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| uint8_t txMode{0}; |
| uint8_t rxMode{0}; |
| uint8_t dcbxMode{0}; |
| }; |
| |
| /** |
| * Human-readable NSM Type 5 Device Mode Index 27 (Power Capping Mode) enum8. |
| */ |
| namespace |
| { |
| inline std::string powerCappingModeToString(uint8_t value) |
| { |
| switch (value) |
| { |
| case NSM_POWER_CAPPING_MODE_DEFAULT: |
| return "Default"; |
| case NSM_POWER_CAPPING_MODE_ENABLED: |
| return "Enabled"; |
| case NSM_POWER_CAPPING_MODE_DISABLED: |
| return "Disabled"; |
| default: |
| return "Unknown(" + std::to_string(static_cast<int>(value)) + ")"; |
| } |
| } |
| |
| inline std::string powerCappingModeFromGetWireToString(uint8_t value) |
| { |
| switch (value) |
| { |
| case NSM_POWER_CAPPING_MODE_ENABLED: |
| return "Enabled"; |
| case NSM_POWER_CAPPING_MODE_DISABLED: |
| return "Disabled"; |
| case NSM_POWER_CAPPING_MODE_DEFAULT: |
| return "Default"; |
| default: |
| return "Unknown(" + std::to_string(static_cast<int>(value)) + ")"; |
| } |
| } |
| |
| inline std::string ltxModeFromGetWireToString(uint8_t value) |
| { |
| switch (value) |
| { |
| case NSM_LTX_MODE_ENABLED: |
| return "Enabled"; |
| case NSM_LTX_MODE_DISABLED: |
| return "Disabled"; |
| case NSM_LTX_MODE_DEFAULT: |
| return "Default"; |
| default: |
| return "Unknown(" + std::to_string(static_cast<int>(value)) + ")"; |
| } |
| } |
| |
| inline std::string uphyModeFromGetWireToString(uint8_t value) |
| { |
| switch (value) |
| { |
| case NSM_UPHY_MODE_ENABLED: |
| return "Enabled"; |
| case NSM_UPHY_MODE_DISABLED: |
| return "Disabled"; |
| case NSM_UPHY_MODE_DEFAULT: |
| return "Default"; |
| default: |
| return "Unknown(" + std::to_string(static_cast<int>(value)) + ")"; |
| } |
| } |
| } // namespace |
| |
| /** |
| * config subcommands targeting NSM Type 5 DEVICE_MODE_POWER_CAPPING (index 27) |
| * so the power-capping enable/disable mode can be read/set without hand-rolling |
| * a raw Get/Set Device Mode Settings v2 command. |
| */ |
| class GetPowerCappingMode : public CommandInterface |
| { |
| public: |
| ~GetPowerCappingMode() = default; |
| GetPowerCappingMode() = delete; |
| GetPowerCappingMode(const GetPowerCappingMode&) = delete; |
| GetPowerCappingMode(GetPowerCappingMode&&) = default; |
| GetPowerCappingMode& operator=(const GetPowerCappingMode&) = delete; |
| GetPowerCappingMode& operator=(GetPowerCappingMode&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetPowerCappingMode(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| {} |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_device_mode_settings_v2_req), |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_device_mode_settings_v2_req( |
| instanceId, static_cast<uint32_t>(DEVICE_MODE_POWER_CAPPING), |
| request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| uint8_t currentData[POWER_CAPPING_MODE_DATA_SIZE] = {}; |
| uint8_t pendingData[POWER_CAPPING_MODE_DATA_SIZE] = {}; |
| uint16_t currentLength = 0; |
| uint16_t pendingLength = 0; |
| |
| /* Probe lengths first: reject oversized mode payloads before decode |
| * copies into the fixed POWER_CAPPING_MODE_DATA_SIZE stack buffers. */ |
| auto rc = decode_get_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode, nullptr, |
| ¤tLength, nullptr, &pendingLength); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| if (currentLength > POWER_CAPPING_MODE_DATA_SIZE || |
| pendingLength > POWER_CAPPING_MODE_DATA_SIZE) |
| { |
| std::cerr << "Power capping mode payload too large: current=" |
| << currentLength << " pending=" << pendingLength |
| << " (max " << POWER_CAPPING_MODE_DATA_SIZE << ")\n"; |
| return; |
| } |
| rc = decode_get_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode, currentData, |
| ¤tLength, pendingData, &pendingLength); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = cc; |
| if (currentLength == POWER_CAPPING_MODE_DATA_SIZE) |
| { |
| result["CurrentMode"] = |
| powerCappingModeFromGetWireToString(currentData[0]); |
| } |
| if (pendingLength == POWER_CAPPING_MODE_DATA_SIZE) |
| { |
| result["PendingMode"] = |
| powerCappingModeFromGetWireToString(pendingData[0]); |
| } |
| if (currentLength == POWER_CAPPING_MODE_DATA_SIZE && |
| pendingLength == POWER_CAPPING_MODE_DATA_SIZE) |
| { |
| result["ResetRequired"] = (pendingData[0] != currentData[0]); |
| } |
| nsmtool::helper::DisplayInJson(result); |
| } |
| }; |
| |
| class SetPowerCappingMode : public CommandInterface |
| { |
| public: |
| ~SetPowerCappingMode() = default; |
| SetPowerCappingMode() = delete; |
| SetPowerCappingMode(const SetPowerCappingMode&) = delete; |
| SetPowerCappingMode(SetPowerCappingMode&&) = default; |
| SetPowerCappingMode& operator=(const SetPowerCappingMode&) = delete; |
| SetPowerCappingMode& operator=(SetPowerCappingMode&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetPowerCappingMode(const char* type, const char* name, |
| CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| auto g = app->add_option_group( |
| "Required", |
| "Set Power Capping Mode (NSM Type 5 idx 27): Default | Enabled | Disabled"); |
| g->add_option("-M, --mode", modeStr, |
| "Power capping mode: Default, Enabled, or Disabled"); |
| g->require_option(1); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| uint8_t mode = 0; |
| std::string m = modeStr; |
| std::transform(m.begin(), m.end(), m.begin(), |
| [](unsigned char c) { return std::tolower(c); }); |
| if (m == "default" || m == "0") |
| { |
| mode = NSM_POWER_CAPPING_MODE_DEFAULT; |
| } |
| else if (m == "enabled" || m == "enable" || m == "1") |
| { |
| mode = NSM_POWER_CAPPING_MODE_ENABLED; |
| } |
| else if (m == "disabled" || m == "disable" || m == "2") |
| { |
| mode = NSM_POWER_CAPPING_MODE_DISABLED; |
| } |
| else |
| { |
| std::cerr << "Invalid mode '" << modeStr |
| << "' (expected Default, Enabled, or Disabled)\n"; |
| return {NSM_SW_ERROR_DATA, {}}; |
| } |
| |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_set_device_mode_settings_v2_req) + |
| POWER_CAPPING_MODE_DATA_SIZE - 1, |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_device_mode_settings_v2_req( |
| instanceId, static_cast<uint32_t>(DEVICE_MODE_POWER_CAPPING), &mode, |
| POWER_CAPPING_MODE_DATA_SIZE, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| auto rc = decode_set_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["Note"] = |
| "Non-volatile; new mode applies after the next device reset."; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| std::string modeStr{}; |
| }; |
| |
| /** |
| * Human-readable NSM Type 5 Device Mode Index 20 (TAV Mode) enum8. |
| */ |
| namespace |
| { |
| inline std::string tavModeFromGetWireToString(uint8_t value) |
| { |
| switch (value) |
| { |
| case NSM_TAV_MODE_ENABLED: |
| return "Enabled"; |
| case NSM_TAV_MODE_DISABLED: |
| return "Disabled"; |
| case NSM_TAV_MODE_DEFAULT: |
| return "Default"; |
| default: |
| return "Unknown(" + std::to_string(static_cast<int>(value)) + ")"; |
| } |
| } |
| } // namespace |
| |
| /** |
| * config subcommands targeting NSM Type 5 DEVICE_MODE_TAV (index 20) |
| * so the TAV mode (NSM Type 5 idx 20) enable/disable mode can be read/set |
| * without hand-rolling a raw Get/Set Device Mode Settings v2 command. |
| */ |
| class GetTAVMode : public CommandInterface |
| { |
| public: |
| ~GetTAVMode() = default; |
| GetTAVMode() = delete; |
| GetTAVMode(const GetTAVMode&) = delete; |
| GetTAVMode(GetTAVMode&&) = default; |
| GetTAVMode& operator=(const GetTAVMode&) = delete; |
| GetTAVMode& operator=(GetTAVMode&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetTAVMode(const char* type, const char* name, CLI::App* app) : |
| CommandInterface(type, name, app) |
| {} |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_device_mode_settings_v2_req), |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_device_mode_settings_v2_req( |
| instanceId, static_cast<uint32_t>(DEVICE_MODE_TAV), request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| uint8_t currentData[TAV_MODE_DATA_SIZE] = {}; |
| uint8_t pendingData[TAV_MODE_DATA_SIZE] = {}; |
| uint16_t currentLength = 0; |
| uint16_t pendingLength = 0; |
| |
| /* Probe lengths first: reject oversized mode payloads before decode |
| * copies into the fixed TAV_MODE_DATA_SIZE stack buffers. */ |
| auto rc = decode_get_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode, nullptr, |
| ¤tLength, nullptr, &pendingLength); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| if (currentLength != TAV_MODE_DATA_SIZE || |
| (pendingLength != 0 && pendingLength != TAV_MODE_DATA_SIZE)) |
| { |
| std::cerr << "TAV mode payload invalid: current=" << currentLength |
| << " pending=" << pendingLength |
| << " (expected current==" << TAV_MODE_DATA_SIZE |
| << ", pending==0 or " << TAV_MODE_DATA_SIZE << ")\n"; |
| return; |
| } |
| rc = decode_get_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode, currentData, |
| ¤tLength, pendingData, &pendingLength); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["CurrentMode"] = tavModeFromGetWireToString(currentData[0]); |
| if (pendingLength == TAV_MODE_DATA_SIZE) |
| { |
| result["PendingMode"] = tavModeFromGetWireToString(pendingData[0]); |
| result["ResetRequired"] = (pendingData[0] != currentData[0]); |
| } |
| nsmtool::helper::DisplayInJson(result); |
| } |
| }; |
| |
| class SetTAVMode : public CommandInterface |
| { |
| public: |
| ~SetTAVMode() = default; |
| SetTAVMode() = delete; |
| SetTAVMode(const SetTAVMode&) = delete; |
| SetTAVMode(SetTAVMode&&) = default; |
| SetTAVMode& operator=(const SetTAVMode&) = delete; |
| SetTAVMode& operator=(SetTAVMode&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetTAVMode(const char* type, const char* name, CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| auto g = app->add_option_group( |
| "Required", |
| "Set TAV Mode (NSM Type 5 idx 20): Default | Enabled | Disabled"); |
| g->add_option("-M, --mode", modeStr, |
| "TAV mode: Default, Enabled, or Disabled"); |
| g->require_option(1); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| uint8_t mode = 0; |
| std::string m = modeStr; |
| std::transform(m.begin(), m.end(), m.begin(), |
| [](unsigned char c) { return std::tolower(c); }); |
| if (m == "default" || m == "0") |
| { |
| mode = NSM_TAV_MODE_DEFAULT; |
| } |
| else if (m == "enabled" || m == "enable" || m == "1") |
| { |
| mode = NSM_TAV_MODE_ENABLED; |
| } |
| else if (m == "disabled" || m == "disable" || m == "2") |
| { |
| mode = NSM_TAV_MODE_DISABLED; |
| } |
| else |
| { |
| std::cerr << "Invalid mode '" << modeStr |
| << "' (expected Default, Enabled, or Disabled)\n"; |
| return {NSM_SW_ERROR_DATA, {}}; |
| } |
| |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_set_device_mode_settings_v2_req) + |
| TAV_MODE_DATA_SIZE - 1, |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_device_mode_settings_v2_req( |
| instanceId, static_cast<uint32_t>(DEVICE_MODE_TAV), &mode, |
| TAV_MODE_DATA_SIZE, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| auto rc = decode_set_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = cc; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| std::string modeStr{}; |
| }; |
| |
| /** |
| * config subcommands targeting NSM Type 5 DEVICE_MODE_LTX (index 29) |
| * so the LTX enable/disable mode can be read/set without hand-rolling a raw |
| * Get/Set Device Mode Settings v2 command. |
| */ |
| class GetLTXMode : public CommandInterface |
| { |
| public: |
| ~GetLTXMode() = default; |
| GetLTXMode() = delete; |
| GetLTXMode(const GetLTXMode&) = delete; |
| GetLTXMode(GetLTXMode&&) = default; |
| GetLTXMode& operator=(const GetLTXMode&) = delete; |
| GetLTXMode& operator=(GetLTXMode&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetLTXMode(const char* type, const char* name, CLI::App* app) : |
| CommandInterface(type, name, app) |
| {} |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_device_mode_settings_v2_req), |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_device_mode_settings_v2_req( |
| instanceId, static_cast<uint32_t>(DEVICE_MODE_LTX), request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| uint8_t currentData[LTX_MODE_DATA_SIZE] = {}; |
| uint8_t pendingData[LTX_MODE_DATA_SIZE] = {}; |
| uint16_t currentLength = 0; |
| uint16_t pendingLength = 0; |
| |
| /* Probe lengths first: reject oversized mode payloads before decode |
| * copies into the fixed LTX_MODE_DATA_SIZE stack buffers. */ |
| auto rc = decode_get_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode, nullptr, |
| ¤tLength, nullptr, &pendingLength); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| /* CurrentMode is mandatory: a length other than exactly |
| * LTX_MODE_DATA_SIZE means the field is absent or malformed, which |
| * is an error condition, not a partial success. PendingMode is |
| * optional but all-or-nothing: only 0 (absent) or exactly |
| * LTX_MODE_DATA_SIZE (present) are acceptable; matches |
| * NsmSwitchLTXMode::handleResponseMsg in nsmSwitch.cpp. */ |
| if (currentLength != LTX_MODE_DATA_SIZE || |
| (pendingLength != 0 && pendingLength != LTX_MODE_DATA_SIZE)) |
| { |
| std::cerr << "LTX mode payload invalid: current=" << currentLength |
| << " pending=" << pendingLength |
| << " (expected current==" << LTX_MODE_DATA_SIZE |
| << ", pending==0 or " << LTX_MODE_DATA_SIZE << ")\n"; |
| return; |
| } |
| rc = decode_get_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode, currentData, |
| ¤tLength, pendingData, &pendingLength); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| if (currentLength != LTX_MODE_DATA_SIZE) |
| { |
| std::cerr << "LTX mode response missing CurrentMode: length=" |
| << currentLength << " (expected " << LTX_MODE_DATA_SIZE |
| << ")\n"; |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["CurrentMode"] = ltxModeFromGetWireToString(currentData[0]); |
| if (pendingLength == LTX_MODE_DATA_SIZE) |
| { |
| result["PendingMode"] = ltxModeFromGetWireToString(pendingData[0]); |
| result["ResetRequired"] = (pendingData[0] != currentData[0]); |
| } |
| nsmtool::helper::DisplayInJson(result); |
| } |
| }; |
| |
| class SetLTXMode : public CommandInterface |
| { |
| public: |
| ~SetLTXMode() = default; |
| SetLTXMode() = delete; |
| SetLTXMode(const SetLTXMode&) = delete; |
| SetLTXMode(SetLTXMode&&) = default; |
| SetLTXMode& operator=(const SetLTXMode&) = delete; |
| SetLTXMode& operator=(SetLTXMode&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetLTXMode(const char* type, const char* name, CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| auto g = app->add_option_group( |
| "Required", |
| "Set LTX Mode (NSM Type 5 idx DEVICE_MODE_LTX): Default | Enabled | Disabled"); |
| g->add_option("-M, --mode", modeStr, |
| "LTX mode: Default, Enabled, or Disabled"); |
| g->require_option(1); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| uint8_t mode = 0; |
| std::string m = modeStr; |
| std::transform(m.begin(), m.end(), m.begin(), |
| [](unsigned char c) { return std::tolower(c); }); |
| if (m == "default" || m == "0") |
| { |
| mode = NSM_LTX_MODE_DEFAULT; |
| } |
| else if (m == "enabled" || m == "enable" || m == "1") |
| { |
| mode = NSM_LTX_MODE_ENABLED; |
| } |
| else if (m == "disabled" || m == "disable" || m == "2") |
| { |
| mode = NSM_LTX_MODE_DISABLED; |
| } |
| else |
| { |
| std::cerr << "Invalid mode '" << modeStr |
| << "' (expected Default, Enabled, or Disabled)\n"; |
| return {NSM_SW_ERROR_DATA, {}}; |
| } |
| |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_set_device_mode_settings_v2_req) + |
| LTX_MODE_DATA_SIZE - 1, |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_device_mode_settings_v2_req( |
| instanceId, static_cast<uint32_t>(DEVICE_MODE_LTX), &mode, |
| LTX_MODE_DATA_SIZE, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| auto rc = decode_set_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["Note"] = |
| "Non-volatile; new mode applies after the next link toggle."; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| std::string modeStr{}; |
| }; |
| |
| /** |
| * config subcommands targeting NSM Type 5 DEVICE_MODE_UPHY (index 28) |
| * so the UPhy enable/disable mode can be read/set without hand-rolling a raw |
| * Get/Set Device Mode Settings v2 command. |
| */ |
| class GetUPhyMode : public CommandInterface |
| { |
| public: |
| ~GetUPhyMode() = default; |
| GetUPhyMode() = delete; |
| GetUPhyMode(const GetUPhyMode&) = delete; |
| GetUPhyMode(GetUPhyMode&&) = default; |
| GetUPhyMode& operator=(const GetUPhyMode&) = delete; |
| GetUPhyMode& operator=(GetUPhyMode&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit GetUPhyMode(const char* type, const char* name, CLI::App* app) : |
| CommandInterface(type, name, app) |
| {} |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_device_mode_settings_v2_req), |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_get_device_mode_settings_v2_req( |
| instanceId, static_cast<uint32_t>(DEVICE_MODE_UPHY), request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| uint8_t currentData[UPHY_MODE_DATA_SIZE] = {}; |
| uint8_t pendingData[UPHY_MODE_DATA_SIZE] = {}; |
| uint16_t currentLength = 0; |
| uint16_t pendingLength = 0; |
| |
| /* Probe lengths first: reject oversized mode payloads before decode |
| * copies into the fixed UPHY_MODE_DATA_SIZE stack buffers. */ |
| auto rc = decode_get_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode, nullptr, |
| ¤tLength, nullptr, &pendingLength); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| /* CurrentMode is mandatory: a length other than exactly |
| * UPHY_MODE_DATA_SIZE means the field is absent or malformed, which |
| * is an error condition, not a partial success. PendingMode is |
| * optional but all-or-nothing: only 0 (absent) or exactly |
| * UPHY_MODE_DATA_SIZE (present) are acceptable; matches |
| * NsmSwitchUPhyMode::handleResponseMsg in nsmSwitch.cpp. */ |
| if (currentLength != UPHY_MODE_DATA_SIZE || |
| (pendingLength != 0 && pendingLength != UPHY_MODE_DATA_SIZE)) |
| { |
| std::cerr << "UPhy mode payload invalid: current=" << currentLength |
| << " pending=" << pendingLength |
| << " (expected current==" << UPHY_MODE_DATA_SIZE |
| << ", pending==0 or " << UPHY_MODE_DATA_SIZE << ")\n"; |
| return; |
| } |
| rc = decode_get_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode, currentData, |
| ¤tLength, pendingData, &pendingLength); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response message error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| if (currentLength != UPHY_MODE_DATA_SIZE) |
| { |
| std::cerr << "UPhy mode response missing CurrentMode: length=" |
| << currentLength << " (expected " << UPHY_MODE_DATA_SIZE |
| << ")\n"; |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["CurrentMode"] = uphyModeFromGetWireToString(currentData[0]); |
| if (pendingLength == UPHY_MODE_DATA_SIZE) |
| { |
| result["PendingMode"] = uphyModeFromGetWireToString(pendingData[0]); |
| result["ResetRequired"] = (pendingData[0] != currentData[0]); |
| } |
| nsmtool::helper::DisplayInJson(result); |
| } |
| }; |
| |
| class SetUPhyMode : public CommandInterface |
| { |
| public: |
| ~SetUPhyMode() = default; |
| SetUPhyMode() = delete; |
| SetUPhyMode(const SetUPhyMode&) = delete; |
| SetUPhyMode(SetUPhyMode&&) = default; |
| SetUPhyMode& operator=(const SetUPhyMode&) = delete; |
| SetUPhyMode& operator=(SetUPhyMode&&) = default; |
| |
| using CommandInterface::CommandInterface; |
| |
| explicit SetUPhyMode(const char* type, const char* name, CLI::App* app) : |
| CommandInterface(type, name, app) |
| { |
| auto g = app->add_option_group( |
| "Required", |
| "Set UPhy Mode (NSM Type 5 idx DEVICE_MODE_UPHY): Default | Enabled | Disabled"); |
| g->add_option("-M, --mode", modeStr, |
| "UPhy mode: Default, Enabled, or Disabled"); |
| g->require_option(1); |
| } |
| |
| std::pair<int, std::vector<uint8_t>> createRequestMsg() override |
| { |
| uint8_t mode = 0; |
| std::string m = modeStr; |
| std::transform(m.begin(), m.end(), m.begin(), |
| [](unsigned char c) { return std::tolower(c); }); |
| if (m == "default" || m == "0") |
| { |
| mode = NSM_UPHY_MODE_DEFAULT; |
| } |
| else if (m == "enabled" || m == "enable" || m == "1") |
| { |
| mode = NSM_UPHY_MODE_ENABLED; |
| } |
| else if (m == "disabled" || m == "disable" || m == "2") |
| { |
| mode = NSM_UPHY_MODE_DISABLED; |
| } |
| else |
| { |
| std::cerr << "Invalid mode '" << modeStr |
| << "' (expected Default, Enabled, or Disabled)\n"; |
| return {NSM_SW_ERROR_DATA, {}}; |
| } |
| |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_set_device_mode_settings_v2_req) + |
| UPHY_MODE_DATA_SIZE - 1, |
| 0); |
| auto request = reinterpret_cast<nsm_msg*>(requestMsg.data()); |
| auto rc = encode_set_device_mode_settings_v2_req( |
| instanceId, static_cast<uint32_t>(DEVICE_MODE_UPHY), &mode, |
| UPHY_MODE_DATA_SIZE, request); |
| return {rc, requestMsg}; |
| } |
| |
| void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| auto rc = decode_set_device_mode_settings_v2_resp( |
| responsePtr, payloadLength, &cc, &reasonCode); |
| if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS) |
| { |
| std::cerr << "Response error: rc=" << rc |
| << ", cc=" << static_cast<int>(cc) |
| << ", reasonCode=" << static_cast<int>(reasonCode) |
| << "\n"; |
| return; |
| } |
| ordered_json result; |
| result["Completion Code"] = cc; |
| result["Note"] = |
| "Non-volatile; new mode applies after the next link toggle."; |
| nsmtool::helper::DisplayInJson(result); |
| } |
| |
| private: |
| std::string modeStr{}; |
| }; |
| |
| void registerCommand(CLI::App& app) |
| { |
| auto config = app.add_subcommand("config", |
| "Device configuration type command"); |
| config->require_subcommand(1); |
| |
| auto setErrorInjectionModeV1 = config->add_subcommand( |
| "SetErrorInjectionModeV1", "Set Error Injection Mode v1"); |
| commands.push_back(std::make_unique<SetErrorInjectionModeV1>( |
| "config", "SetErrorInjectionModeV1", setErrorInjectionModeV1)); |
| |
| auto getErrorInjectionModeV1 = config->add_subcommand( |
| "GetErrorInjectionModeV1", "Get Error Injection Mode v1"); |
| commands.push_back(std::make_unique<GetErrorInjectionModeV1>( |
| "config", "GetErrorInjectionModeV1", getErrorInjectionModeV1)); |
| |
| auto getSupportedErrorInjectionTypesV1 = |
| config->add_subcommand("GetSupportedErrorInjectionTypesV1", |
| "Get Supported Error Injection Types v1"); |
| commands.push_back(std::make_unique<GetSupportedErrorInjectionTypesV1>( |
| "config", "GetSupportedErrorInjectionTypesV1", |
| getSupportedErrorInjectionTypesV1)); |
| |
| auto setErrorInjectionPayload = config->add_subcommand( |
| "SetErrorInjectionPayload", "Set Error Injection Payload"); |
| commands.push_back(std::make_unique<SetErrorInjectionPayload>( |
| "config", "SetErrorInjectionPayload", setErrorInjectionPayload)); |
| |
| auto getErrorInjectionPayload = config->add_subcommand( |
| "GetErrorInjectionPayload", "Get Current Error Injection Payload"); |
| commands.push_back(std::make_unique<GetErrorInjectionPayload>( |
| "config", "GetErrorInjectionPayload", getErrorInjectionPayload)); |
| |
| auto activateErrorInjectionPayload = config->add_subcommand( |
| "ActivateErrorInjectionPayload", "Activate Error Injection Payload"); |
| commands.push_back(std::make_unique<ActivateErrorInjectionPayload>( |
| "config", "ActivateErrorInjectionPayload", |
| activateErrorInjectionPayload)); |
| |
| auto setCurrentErrorInjectionTypesV1 = |
| config->add_subcommand("SetCurrentErrorInjectionTypesV1", |
| "Set Current Error Injection Types v1"); |
| commands.push_back(std::make_unique<SetCurrentErrorInjectionTypesV1>( |
| "config", "SetCurrentErrorInjectionTypesV1", |
| setCurrentErrorInjectionTypesV1)); |
| |
| auto getCurrentErrorInjectionTypesV1 = |
| config->add_subcommand("GetCurrentErrorInjectionTypesV1", |
| "Get Current Error Injection Types v1"); |
| commands.push_back(std::make_unique<GetCurrentErrorInjectionTypesV1>( |
| "config", "GetCurrentErrorInjectionTypesV1", |
| getCurrentErrorInjectionTypesV1)); |
| |
| auto getFpgaDiagnosticsSettings = |
| config->add_subcommand("GetFpgaDiagnosticsSettings", |
| "Get FPGA Diagnostics Settings for data index "); |
| commands.push_back(std::make_unique<GetFpgaDiagnosticsSettings>( |
| "config", "GetFpgaDiagnosticsSettings", getFpgaDiagnosticsSettings)); |
| |
| auto enableDisableGpuIstMode = config->add_subcommand( |
| "EnableDisableGpuIstMode", |
| "Enable/Disable GPUs IST Mode Settings for device index "); |
| commands.push_back(std::make_unique<EnableDisableGpuIstMode>( |
| "config", "EnableDisableGpuIstMode", enableDisableGpuIstMode)); |
| |
| auto getReconfigurationPermissionsV1 = |
| config->add_subcommand("GetReconfigurationPermissionsV1", |
| "Get Reconfiguration Permissions v1"); |
| commands.push_back(std::make_unique<GetReconfigurationPermissionsV1>( |
| "config", "GetReconfigurationPermissionsV1", |
| getReconfigurationPermissionsV1)); |
| |
| auto setReconfigurationPermissionsV1 = |
| config->add_subcommand("SetReconfigurationPermissionsV1", |
| "Set Reconfiguration Permissions v1"); |
| commands.push_back(std::make_unique<SetReconfigurationPermissionsV1>( |
| "config", "SetReconfigurationPermissionsV1", |
| setReconfigurationPermissionsV1)); |
| |
| auto getConfidentialComputeModeV1 = config->add_subcommand( |
| "GetConfidentialComputeModeV1", "Get Confidential Compute Mode Data"); |
| commands.push_back(std::make_unique<GetConfidentialComputeModeV1>( |
| "config", "GetConfidentialComputeModeV1", |
| getConfidentialComputeModeV1)); |
| |
| auto setConfidentialComputeModeV1 = config->add_subcommand( |
| "SetConfidentialComputeModeV1", "Set Confidential Compute Mode Data"); |
| commands.push_back(std::make_unique<SetConfidentialComputeModeV1>( |
| "config", "SetConfidentialComputeModeV1", |
| setConfidentialComputeModeV1)); |
| |
| auto getDeviceModeSettings = config->add_subcommand( |
| "GetDevicemodeSettings", "Get device mode settings"); |
| commands.push_back(std::make_unique<GetDevicemodeSettings>( |
| "config", "GetDevicemodeSettings", getDeviceModeSettings)); |
| |
| auto setDeviceModeSettings = config->add_subcommand( |
| "SetDevicemodeSettings", "Set device mode settings"); |
| commands.push_back(std::make_unique<SetDevicemodeSettings>( |
| "config", "SetDevicemodeSettings", setDeviceModeSettings)); |
| |
| auto getDeviceModeSettingsV2 = config->add_subcommand( |
| "GetDeviceModeSettingsV2", "Get device mode settings v2 (0x83)"); |
| commands.push_back(std::make_unique<GetDeviceModeSettingsV2>( |
| "config", "GetDeviceModeSettingsV2", getDeviceModeSettingsV2)); |
| |
| auto setDeviceModeSettingsV2 = config->add_subcommand( |
| "SetDeviceModeSettingsV2", "Set device mode settings v2 (0x82)"); |
| commands.push_back(std::make_unique<SetDeviceModeSettingsV2>( |
| "config", "SetDeviceModeSettingsV2", setDeviceModeSettingsV2)); |
| |
| auto setDeviceConfig = config->add_subcommand( |
| "SetDeviceConfig", "Set Device Config Type 5 command 0x10 (V2)"); |
| commands.push_back(std::make_unique<SetDeviceConfig>( |
| "config", "SetDeviceConfig", setDeviceConfig)); |
| |
| auto getDeviceConfig = config->add_subcommand( |
| "GetDeviceConfig", "Get Device Config Type 5 command 0x11 (V2)"); |
| commands.push_back(std::make_unique<GetDeviceConfig>( |
| "config", "GetDeviceConfig", getDeviceConfig)); |
| |
| // OOB Miswiring Detection |
| auto getLldpMode = config->add_subcommand( |
| "GetLLDPMode", "Get LLDP mode bitfield (NSM Type 5 idx 24)"); |
| commands.push_back( |
| std::make_unique<GetLLDPMode>("config", "GetLLDPMode", getLldpMode)); |
| |
| auto setLldpMode = config->add_subcommand( |
| "SetLLDPMode", "Set LLDP mode bitfield (NSM Type 5 idx 24)"); |
| commands.push_back( |
| std::make_unique<SetLLDPMode>("config", "SetLLDPMode", setLldpMode)); |
| |
| auto getPowerCappingMode = config->add_subcommand( |
| "GetPowerCappingMode", "Get power capping mode (NSM Type 5 idx 27)"); |
| commands.push_back(std::make_unique<GetPowerCappingMode>( |
| "config", "GetPowerCappingMode", getPowerCappingMode)); |
| |
| auto setPowerCappingMode = config->add_subcommand( |
| "SetPowerCappingMode", "Set power capping mode (NSM Type 5 idx 27)"); |
| commands.push_back(std::make_unique<SetPowerCappingMode>( |
| "config", "SetPowerCappingMode", setPowerCappingMode)); |
| |
| auto getTAVMode = config->add_subcommand( |
| "GetTAVMode", "Get TAV mode (NSM Type 5 idx 20)"); |
| commands.push_back( |
| std::make_unique<GetTAVMode>("config", "GetTAVMode", getTAVMode)); |
| |
| auto setTAVMode = config->add_subcommand( |
| "SetTAVMode", "Set TAV mode (NSM Type 5 idx 20)"); |
| commands.push_back( |
| std::make_unique<SetTAVMode>("config", "SetTAVMode", setTAVMode)); |
| |
| auto getLTXMode = config->add_subcommand( |
| "GetLTXMode", "Get LTX mode (NSM Type 5 idx DEVICE_MODE_LTX)"); |
| commands.push_back( |
| std::make_unique<GetLTXMode>("config", "GetLTXMode", getLTXMode)); |
| |
| auto setLTXMode = config->add_subcommand( |
| "SetLTXMode", "Set LTX mode (NSM Type 5 idx DEVICE_MODE_LTX)"); |
| commands.push_back( |
| std::make_unique<SetLTXMode>("config", "SetLTXMode", setLTXMode)); |
| |
| auto getUPhyMode = config->add_subcommand( |
| "GetUPhyMode", "Get UPhy mode (NSM Type 5 idx DEVICE_MODE_UPHY)"); |
| commands.push_back( |
| std::make_unique<GetUPhyMode>("config", "GetUPhyMode", getUPhyMode)); |
| |
| auto setUPhyMode = config->add_subcommand( |
| "SetUPhyMode", "Set UPhy mode (NSM Type 5 idx DEVICE_MODE_UPHY)"); |
| commands.push_back( |
| std::make_unique<SetUPhyMode>("config", "SetUPhyMode", setUPhyMode)); |
| } |
| |
| } // namespace config |
| |
| } // namespace nsmtool |