195e6b3c1SJohn Wang #include "bios_integer_attribute.hpp" 295e6b3c1SJohn Wang 3d130e1a3SDeepak Kodihalli #include "common/utils.hpp" 495e6b3c1SJohn Wang 5*49cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp> 6*49cfb138SRiya Dixit 7*49cfb138SRiya Dixit PHOSPHOR_LOG2_USING; 8*49cfb138SRiya Dixit 95079ac4aSBrad Bishop using namespace pldm::utils; 105079ac4aSBrad Bishop 1195e6b3c1SJohn Wang namespace pldm 1295e6b3c1SJohn Wang { 1395e6b3c1SJohn Wang namespace responder 1495e6b3c1SJohn Wang { 1595e6b3c1SJohn Wang namespace bios 1695e6b3c1SJohn Wang { 1795e6b3c1SJohn Wang BIOSIntegerAttribute::BIOSIntegerAttribute(const Json& entry, 1895e6b3c1SJohn Wang DBusHandler* const dbusHandler) : 1995e6b3c1SJohn Wang BIOSAttribute(entry, dbusHandler) 2095e6b3c1SJohn Wang { 2195e6b3c1SJohn Wang std::string attr = entry.at("attribute_name"); 2295e6b3c1SJohn Wang 2395e6b3c1SJohn Wang integerInfo.lowerBound = entry.at("lower_bound"); 2495e6b3c1SJohn Wang integerInfo.upperBound = entry.at("upper_bound"); 2595e6b3c1SJohn Wang integerInfo.scalarIncrement = entry.at("scalar_increment"); 2695e6b3c1SJohn Wang integerInfo.defaultValue = entry.at("default_value"); 2795e6b3c1SJohn Wang pldm_bios_table_attr_entry_integer_info info = { 2895e6b3c1SJohn Wang 0, 2995e6b3c1SJohn Wang readOnly, 3095e6b3c1SJohn Wang integerInfo.lowerBound, 3195e6b3c1SJohn Wang integerInfo.upperBound, 3295e6b3c1SJohn Wang integerInfo.scalarIncrement, 3395e6b3c1SJohn Wang integerInfo.defaultValue, 3495e6b3c1SJohn Wang }; 3595e6b3c1SJohn Wang const char* errmsg = nullptr; 3695e6b3c1SJohn Wang auto rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg); 3795e6b3c1SJohn Wang if (rc != PLDM_SUCCESS) 3895e6b3c1SJohn Wang { 39*49cfb138SRiya Dixit error( 40*49cfb138SRiya Dixit "Wrong filed for integer attribute, ATTRIBUTE_NAME={ATTR_NAME} ERRMSG= {ERR_MSG} LOWER_BOUND={LOW_BOUND} UPPER_BOUND={UPPER_BOUND} DEFAULT_VALUE={DEF_VAL} SCALAR_INCREMENT={SCALAR_INCREMENT}", 41*49cfb138SRiya Dixit "ATTR_NAME", attr.c_str(), "ERR_MSG", errmsg, "LOW_BOUND", 42*49cfb138SRiya Dixit integerInfo.lowerBound, "UPPER_BOUND", integerInfo.upperBound, 43*49cfb138SRiya Dixit "DEF_VAL", integerInfo.defaultValue, "SCALAR_INCREMENT", 44*49cfb138SRiya Dixit integerInfo.scalarIncrement); 4595e6b3c1SJohn Wang throw std::invalid_argument("Wrong field for integer attribute"); 4695e6b3c1SJohn Wang } 4795e6b3c1SJohn Wang } 4895e6b3c1SJohn Wang 4995e6b3c1SJohn Wang void BIOSIntegerAttribute::setAttrValueOnDbus( 5095e6b3c1SJohn Wang const pldm_bios_attr_val_table_entry* attrValueEntry, 5195e6b3c1SJohn Wang const pldm_bios_attr_table_entry*, const BIOSStringTable&) 5295e6b3c1SJohn Wang { 535bb9edb9SGeorge Liu if (!dBusMap.has_value()) 5495e6b3c1SJohn Wang { 5595e6b3c1SJohn Wang return; 5695e6b3c1SJohn Wang } 5795e6b3c1SJohn Wang auto currentValue = 5895e6b3c1SJohn Wang table::attribute_value::decodeIntegerEntry(attrValueEntry); 5995e6b3c1SJohn Wang 6095e6b3c1SJohn Wang if (dBusMap->propertyType == "uint8_t") 6195e6b3c1SJohn Wang { 6295e6b3c1SJohn Wang return dbusHandler->setDbusProperty(*dBusMap, 6395e6b3c1SJohn Wang static_cast<uint8_t>(currentValue)); 6495e6b3c1SJohn Wang } 6595e6b3c1SJohn Wang else if (dBusMap->propertyType == "uint16_t") 6695e6b3c1SJohn Wang { 6795e6b3c1SJohn Wang return dbusHandler->setDbusProperty( 6895e6b3c1SJohn Wang *dBusMap, static_cast<uint16_t>(currentValue)); 6995e6b3c1SJohn Wang } 7095e6b3c1SJohn Wang else if (dBusMap->propertyType == "int16_t") 7195e6b3c1SJohn Wang { 7295e6b3c1SJohn Wang return dbusHandler->setDbusProperty(*dBusMap, 7395e6b3c1SJohn Wang static_cast<int16_t>(currentValue)); 7495e6b3c1SJohn Wang } 7595e6b3c1SJohn Wang else if (dBusMap->propertyType == "uint32_t") 7695e6b3c1SJohn Wang { 7795e6b3c1SJohn Wang return dbusHandler->setDbusProperty( 7895e6b3c1SJohn Wang *dBusMap, static_cast<uint32_t>(currentValue)); 7995e6b3c1SJohn Wang } 8095e6b3c1SJohn Wang else if (dBusMap->propertyType == "int32_t") 8195e6b3c1SJohn Wang { 8295e6b3c1SJohn Wang return dbusHandler->setDbusProperty(*dBusMap, 8395e6b3c1SJohn Wang static_cast<int32_t>(currentValue)); 8495e6b3c1SJohn Wang } 8595e6b3c1SJohn Wang else if (dBusMap->propertyType == "uint64_t") 8695e6b3c1SJohn Wang { 8795e6b3c1SJohn Wang return dbusHandler->setDbusProperty(*dBusMap, currentValue); 8895e6b3c1SJohn Wang } 8995e6b3c1SJohn Wang else if (dBusMap->propertyType == "int64_t") 9095e6b3c1SJohn Wang { 9195e6b3c1SJohn Wang return dbusHandler->setDbusProperty(*dBusMap, 9295e6b3c1SJohn Wang static_cast<int64_t>(currentValue)); 9395e6b3c1SJohn Wang } 94aca897b7SGeorge Liu else if (dBusMap->propertyType == "double") 95aca897b7SGeorge Liu { 96aca897b7SGeorge Liu return dbusHandler->setDbusProperty(*dBusMap, 97aca897b7SGeorge Liu static_cast<double>(currentValue)); 98aca897b7SGeorge Liu } 9995e6b3c1SJohn Wang 100*49cfb138SRiya Dixit error("Unsupported property type on dbus: {DBUS_PROP}", "DBUS_PROP", 101*49cfb138SRiya Dixit dBusMap->propertyType); 10295e6b3c1SJohn Wang throw std::invalid_argument("dbus type error"); 10395e6b3c1SJohn Wang } 10495e6b3c1SJohn Wang 105ca7b2524STom Joseph void BIOSIntegerAttribute::constructEntry( 106ca7b2524STom Joseph const BIOSStringTable& stringTable, Table& attrTable, Table& attrValueTable, 107ca7b2524STom Joseph std::optional<std::variant<int64_t, std::string>> optAttributeValue) 10895e6b3c1SJohn Wang { 10995e6b3c1SJohn Wang pldm_bios_table_attr_entry_integer_info info = { 11095e6b3c1SJohn Wang stringTable.findHandle(name), readOnly, 11195e6b3c1SJohn Wang integerInfo.lowerBound, integerInfo.upperBound, 11295e6b3c1SJohn Wang integerInfo.scalarIncrement, integerInfo.defaultValue, 11395e6b3c1SJohn Wang }; 11495e6b3c1SJohn Wang 11595e6b3c1SJohn Wang auto attrTableEntry = 11695e6b3c1SJohn Wang table::attribute::constructIntegerEntry(attrTable, &info); 11795e6b3c1SJohn Wang 11895e6b3c1SJohn Wang auto [attrHandle, attrType, _] = 11995e6b3c1SJohn Wang table::attribute::decodeHeader(attrTableEntry); 12095e6b3c1SJohn Wang 121ca7b2524STom Joseph int64_t currentValue{}; 122ca7b2524STom Joseph if (optAttributeValue.has_value()) 123ca7b2524STom Joseph { 124ca7b2524STom Joseph auto attributeValue = optAttributeValue.value(); 125ca7b2524STom Joseph if (attributeValue.index() == 0) 126ca7b2524STom Joseph { 127ca7b2524STom Joseph currentValue = std::get<int64_t>(attributeValue); 128ca7b2524STom Joseph } 129ca7b2524STom Joseph else 130ca7b2524STom Joseph { 131ca7b2524STom Joseph currentValue = getAttrValue(); 132ca7b2524STom Joseph } 133ca7b2524STom Joseph } 134ca7b2524STom Joseph else 135ca7b2524STom Joseph { 136ca7b2524STom Joseph currentValue = getAttrValue(); 137ca7b2524STom Joseph } 138ca7b2524STom Joseph 13995e6b3c1SJohn Wang table::attribute_value::constructIntegerEntry(attrValueTable, attrHandle, 14095e6b3c1SJohn Wang attrType, currentValue); 14195e6b3c1SJohn Wang } 14295e6b3c1SJohn Wang 14346ece063SSampa Misra uint64_t BIOSIntegerAttribute::getAttrValue(const PropertyValue& propertyValue) 14495e6b3c1SJohn Wang { 145081d03b6SAndrew Geissler uint64_t value = 0; 14695e6b3c1SJohn Wang if (dBusMap->propertyType == "uint8_t") 14795e6b3c1SJohn Wang { 14895e6b3c1SJohn Wang value = std::get<uint8_t>(propertyValue); 14995e6b3c1SJohn Wang } 15095e6b3c1SJohn Wang else if (dBusMap->propertyType == "uint16_t") 15195e6b3c1SJohn Wang { 15295e6b3c1SJohn Wang value = std::get<uint16_t>(propertyValue); 15395e6b3c1SJohn Wang } 15495e6b3c1SJohn Wang else if (dBusMap->propertyType == "int16_t") 15595e6b3c1SJohn Wang { 15695e6b3c1SJohn Wang value = std::get<int16_t>(propertyValue); 15795e6b3c1SJohn Wang } 15895e6b3c1SJohn Wang else if (dBusMap->propertyType == "uint32_t") 15995e6b3c1SJohn Wang { 16095e6b3c1SJohn Wang value = std::get<uint32_t>(propertyValue); 16195e6b3c1SJohn Wang } 16295e6b3c1SJohn Wang else if (dBusMap->propertyType == "int32_t") 16395e6b3c1SJohn Wang { 16495e6b3c1SJohn Wang value = std::get<int32_t>(propertyValue); 16595e6b3c1SJohn Wang } 16695e6b3c1SJohn Wang else if (dBusMap->propertyType == "uint64_t") 16795e6b3c1SJohn Wang { 16895e6b3c1SJohn Wang value = std::get<uint64_t>(propertyValue); 16995e6b3c1SJohn Wang } 17095e6b3c1SJohn Wang else if (dBusMap->propertyType == "int64_t") 17195e6b3c1SJohn Wang { 17295e6b3c1SJohn Wang value = std::get<int64_t>(propertyValue); 17395e6b3c1SJohn Wang } 174aca897b7SGeorge Liu else if (dBusMap->propertyType == "double") 175aca897b7SGeorge Liu { 176aca897b7SGeorge Liu value = std::get<double>(propertyValue); 177aca897b7SGeorge Liu } 178081d03b6SAndrew Geissler else 179081d03b6SAndrew Geissler { 180*49cfb138SRiya Dixit error("Unsupported property type for getAttrValue: {DBUS_PROP}", 181*49cfb138SRiya Dixit "DBUS_PROP", dBusMap->propertyType); 182081d03b6SAndrew Geissler throw std::invalid_argument("dbus type error"); 183081d03b6SAndrew Geissler } 18495e6b3c1SJohn Wang return value; 18595e6b3c1SJohn Wang } 18695e6b3c1SJohn Wang 18795e6b3c1SJohn Wang uint64_t BIOSIntegerAttribute::getAttrValue() 18895e6b3c1SJohn Wang { 1895bb9edb9SGeorge Liu if (!dBusMap.has_value()) 19095e6b3c1SJohn Wang { 19195e6b3c1SJohn Wang return integerInfo.defaultValue; 19295e6b3c1SJohn Wang } 19395e6b3c1SJohn Wang 19495e6b3c1SJohn Wang try 19595e6b3c1SJohn Wang { 19695e6b3c1SJohn Wang auto propertyValue = dbusHandler->getDbusPropertyVariant( 19795e6b3c1SJohn Wang dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(), 19895e6b3c1SJohn Wang dBusMap->interface.c_str()); 19995e6b3c1SJohn Wang 20095e6b3c1SJohn Wang return getAttrValue(propertyValue); 20195e6b3c1SJohn Wang } 20295e6b3c1SJohn Wang catch (const std::exception& e) 20395e6b3c1SJohn Wang { 204*49cfb138SRiya Dixit error("Get Integer Attribute Value Error: AttributeName = {ATTR_NAME}", 205*49cfb138SRiya Dixit "ATTR_NAME", name); 20695e6b3c1SJohn Wang return integerInfo.defaultValue; 20795e6b3c1SJohn Wang } 20895e6b3c1SJohn Wang } 20995e6b3c1SJohn Wang 21046ece063SSampa Misra int BIOSIntegerAttribute::updateAttrVal(Table& newValue, uint16_t attrHdl, 21146ece063SSampa Misra uint8_t attrType, 21246ece063SSampa Misra const PropertyValue& newPropVal) 21346ece063SSampa Misra { 21446ece063SSampa Misra auto newVal = getAttrValue(newPropVal); 21546ece063SSampa Misra table::attribute_value::constructIntegerEntry(newValue, attrHdl, attrType, 21646ece063SSampa Misra newVal); 21746ece063SSampa Misra return PLDM_SUCCESS; 21846ece063SSampa Misra } 21946ece063SSampa Misra 2201244acfdSGeorge Liu void BIOSIntegerAttribute::generateAttributeEntry( 2211244acfdSGeorge Liu const std::variant<int64_t, std::string>& attributevalue, 2221244acfdSGeorge Liu Table& attrValueEntry) 2231244acfdSGeorge Liu { 2241244acfdSGeorge Liu attrValueEntry.resize(sizeof(pldm_bios_attr_val_table_entry) + 2251244acfdSGeorge Liu sizeof(int64_t) - 1); 2261244acfdSGeorge Liu 2271244acfdSGeorge Liu auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>( 2281244acfdSGeorge Liu attrValueEntry.data()); 2291244acfdSGeorge Liu 2301244acfdSGeorge Liu int64_t value = std::get<int64_t>(attributevalue); 2311244acfdSGeorge Liu entry->attr_type = 3; 2321244acfdSGeorge Liu memcpy(entry->value, &value, sizeof(int64_t)); 2331244acfdSGeorge Liu } 2341244acfdSGeorge Liu 23595e6b3c1SJohn Wang } // namespace bios 23695e6b3c1SJohn Wang } // namespace responder 23795e6b3c1SJohn Wang } // namespace pldm 238