195e6b3c1SJohn Wang #include "bios_integer_attribute.hpp"
295e6b3c1SJohn Wang
3d130e1a3SDeepak Kodihalli #include "common/utils.hpp"
495e6b3c1SJohn Wang
549cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp>
649cfb138SRiya Dixit
749cfb138SRiya Dixit PHOSPHOR_LOG2_USING;
849cfb138SRiya 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 {
BIOSIntegerAttribute(const Json & entry,DBusHandler * const dbusHandler)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 {
3949cfb138SRiya Dixit error(
40*2576aecdSManojkiran Eda "Wrong field for integer attribute '{ATTRIBUTE}', error '{ERROR}', lower bound '{LOW_BOUND}', upper bound '{UPPER_BOUND}', default value '{DEFAULT_VALUE}' and scalar increment '{SCALAR_INCREMENT}'",
4189644441SRiya Dixit "ATTRIBUTE", attr, "ERROR", errmsg, "LOW_BOUND",
4249cfb138SRiya Dixit integerInfo.lowerBound, "UPPER_BOUND", integerInfo.upperBound,
4389644441SRiya Dixit "DEFAULT_VALUE", integerInfo.defaultValue, "SCALAR_INCREMENT",
4449cfb138SRiya Dixit integerInfo.scalarIncrement);
4595e6b3c1SJohn Wang throw std::invalid_argument("Wrong field for integer attribute");
4695e6b3c1SJohn Wang }
4795e6b3c1SJohn Wang }
4895e6b3c1SJohn Wang
setAttrValueOnDbus(const pldm_bios_attr_val_table_entry * attrValueEntry,const pldm_bios_attr_table_entry *,const BIOSStringTable &)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
10089644441SRiya Dixit error("Unsupported property type '{TYPE}' on dbus", "TYPE",
10149cfb138SRiya Dixit dBusMap->propertyType);
10295e6b3c1SJohn Wang throw std::invalid_argument("dbus type error");
10395e6b3c1SJohn Wang }
10495e6b3c1SJohn Wang
constructEntry(const BIOSStringTable & stringTable,Table & attrTable,Table & attrValueTable,std::optional<std::variant<int64_t,std::string>> optAttributeValue)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
1156da4f91bSPatrick Williams auto attrTableEntry = table::attribute::constructIntegerEntry(attrTable,
1166da4f91bSPatrick Williams &info);
11795e6b3c1SJohn Wang
1186da4f91bSPatrick Williams auto [attrHandle, attrType,
1196da4f91bSPatrick Williams _] = 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
getAttrValue(const PropertyValue & propertyValue)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 {
18089644441SRiya Dixit error("Unsupported property type '{TYPE}' for getAttrValue", "TYPE",
18189644441SRiya Dixit dBusMap->propertyType);
182081d03b6SAndrew Geissler throw std::invalid_argument("dbus type error");
183081d03b6SAndrew Geissler }
18495e6b3c1SJohn Wang return value;
18595e6b3c1SJohn Wang }
18695e6b3c1SJohn Wang
getAttrValue()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 {
20458cbcaf2SKamalkumar Patel error(
20589644441SRiya Dixit "Error getting integer attribute '{ATTRIBUTE}' at path '{PATH}' and interface '{INTERFACE}' for property '{PROPERTY}', error - {ERROR}",
20689644441SRiya Dixit "ATTRIBUTE", name, "PATH", dBusMap->objectPath, "INTERFACE",
20789644441SRiya Dixit dBusMap->interface, "PROPERTY", dBusMap->propertyName, "ERROR", e);
20895e6b3c1SJohn Wang return integerInfo.defaultValue;
20995e6b3c1SJohn Wang }
21095e6b3c1SJohn Wang }
21195e6b3c1SJohn Wang
updateAttrVal(Table & newValue,uint16_t attrHdl,uint8_t attrType,const PropertyValue & newPropVal)21246ece063SSampa Misra int BIOSIntegerAttribute::updateAttrVal(Table& newValue, uint16_t attrHdl,
21346ece063SSampa Misra uint8_t attrType,
21446ece063SSampa Misra const PropertyValue& newPropVal)
21546ece063SSampa Misra {
21646ece063SSampa Misra auto newVal = getAttrValue(newPropVal);
21746ece063SSampa Misra table::attribute_value::constructIntegerEntry(newValue, attrHdl, attrType,
21846ece063SSampa Misra newVal);
21946ece063SSampa Misra return PLDM_SUCCESS;
22046ece063SSampa Misra }
22146ece063SSampa Misra
generateAttributeEntry(const std::variant<int64_t,std::string> & attributevalue,Table & attrValueEntry)2221244acfdSGeorge Liu void BIOSIntegerAttribute::generateAttributeEntry(
2231244acfdSGeorge Liu const std::variant<int64_t, std::string>& attributevalue,
2241244acfdSGeorge Liu Table& attrValueEntry)
2251244acfdSGeorge Liu {
2261244acfdSGeorge Liu attrValueEntry.resize(sizeof(pldm_bios_attr_val_table_entry) +
2271244acfdSGeorge Liu sizeof(int64_t) - 1);
2281244acfdSGeorge Liu
2291244acfdSGeorge Liu auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>(
2301244acfdSGeorge Liu attrValueEntry.data());
2311244acfdSGeorge Liu
2321244acfdSGeorge Liu int64_t value = std::get<int64_t>(attributevalue);
2331244acfdSGeorge Liu entry->attr_type = 3;
2341244acfdSGeorge Liu memcpy(entry->value, &value, sizeof(int64_t));
2351244acfdSGeorge Liu }
2361244acfdSGeorge Liu
23795e6b3c1SJohn Wang } // namespace bios
23895e6b3c1SJohn Wang } // namespace responder
23995e6b3c1SJohn Wang } // namespace pldm
240