oem_ibm: Add Slot enable infrastructure in BMC
With this commit PDRs are created for each of these
PCIe slots and adapters which have a corresponding
entry in the entity associate map. The sensor/effector
states are monitored and accordingly D-Bus calls are
sent for enabling a slot, process property change
of a PCIe slot, etc.
Tested By: SIMICS power on/off and reset reload.
Signed-off-by: Manojkiran Eda <manojkiran.eda@gmail.com>
Change-Id: I51b79b75c909ddf2cc29872fec6aa01c2d56b418
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
index 6a39328..9721bc1 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
@@ -1,11 +1,13 @@
#include "oem_ibm_handler.hpp"
+#include "collect_slot_vpd.hpp"
#include "file_io_type_lid.hpp"
#include "libpldmresponder/file_io.hpp"
#include "libpldmresponder/pdr_utils.hpp"
#include <libpldm/entity.h>
#include <libpldm/oem/ibm/entity.h>
+#include <libpldm/pldm.h>
#include <phosphor-logging/lg2.hpp>
#include <xyz/openbmc_project/State/BMC/client.hpp>
@@ -24,9 +26,11 @@
int pldm::responder::oem_ibm_platform::Handler::
getOemStateSensorReadingsHandler(
pldm::pdr::EntityType entityType, EntityInstance entityInstance,
- StateSetId stateSetId, CompositeCount compSensorCnt,
+ ContainerID containerId, StateSetId stateSetId,
+ CompositeCount compSensorCnt, uint16_t /*sensorId*/,
std::vector<get_sensor_state_field>& stateField)
{
+ auto& entityAssociationMap = getAssociateEntityMap();
int rc = PLDM_SUCCESS;
stateField.clear();
@@ -38,6 +42,20 @@
{
sensorOpState = fetchBootSide(entityInstance, codeUpdate);
}
+ else if (entityType == PLDM_ENTITY_SLOT &&
+ stateSetId == PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE)
+ {
+ for (const auto& [key, value] : entityAssociationMap)
+ {
+ if (value.entity_type == entityType &&
+ value.entity_instance_num == entityInstance &&
+ value.entity_container_id == containerId)
+ {
+ sensorOpState = slotHandler->fetchSlotSensorState(key);
+ break;
+ }
+ }
+ }
else
{
rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
@@ -53,10 +71,10 @@
oemSetStateEffecterStatesHandler(
uint16_t entityType, uint16_t entityInstance, uint16_t stateSetId,
uint8_t compEffecterCnt,
- std::vector<set_effecter_state_field>& stateField,
- uint16_t /*effecterId*/)
+ std::vector<set_effecter_state_field>& stateField, uint16_t effecterId)
{
int rc = PLDM_SUCCESS;
+ auto& entityAssociationMap = getAssociateEntityMap();
for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
{
@@ -141,6 +159,11 @@
this, std::placeholders::_1));
}
}
+ else if (stateSetId == PLDM_OEM_IBM_PCIE_SLOT_EFFECTER_STATE)
+ {
+ slotHandler->enableSlot(effecterId, entityAssociationMap,
+ stateField[currState].effecter_state);
+ }
else
{
rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
@@ -206,6 +229,71 @@
repo.addRecord(pdrEntry);
}
+void buildAllSlotEnableEffecterPDR(oem_ibm_platform::Handler* platformHandler,
+ pdr_utils::Repo& repo,
+ const std::vector<std::string>& slotobjpaths)
+{
+ size_t pdrSize = 0;
+ pdrSize = sizeof(pldm_state_effecter_pdr) +
+ sizeof(state_effecter_possible_states);
+ std::vector<uint8_t> entry{};
+ entry.resize(pdrSize);
+ pldm_state_effecter_pdr* pdr =
+ reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
+ if (!pdr)
+ {
+ error("Failed to get record by PDR type, ERROR:{ERR}", "ERR", lg2::hex,
+ static_cast<unsigned>(PLDM_PLATFORM_INVALID_EFFECTER_ID));
+ return;
+ }
+
+ auto& associatedEntityMap = platformHandler->getAssociateEntityMap();
+ for (const auto& entity_path : slotobjpaths)
+ {
+ pdr->hdr.record_handle = 0;
+ pdr->hdr.version = 1;
+ pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
+ pdr->hdr.record_change_num = 0;
+ pdr->hdr.length =
+ sizeof(pldm_state_effecter_pdr) - sizeof(pldm_pdr_hdr);
+ pdr->terminus_handle = TERMINUS_HANDLE;
+ pdr->effecter_id = platformHandler->getNextEffecterId();
+
+ if (entity_path != "" && associatedEntityMap.contains(entity_path))
+ {
+ pdr->entity_type = associatedEntityMap.at(entity_path).entity_type;
+ pdr->entity_instance =
+ associatedEntityMap.at(entity_path).entity_instance_num;
+ pdr->container_id =
+ associatedEntityMap.at(entity_path).entity_container_id;
+ platformHandler->effecterIdToDbusMap[pdr->effecter_id] =
+ entity_path;
+ }
+ else
+ {
+ // the slots are not present, dont create the PDR
+ continue;
+ }
+ pdr->effecter_semantic_id = 0;
+ pdr->effecter_init = PLDM_NO_INIT;
+ pdr->has_description_pdr = false;
+ pdr->composite_effecter_count = 1;
+
+ auto* possibleStatesPtr = pdr->possible_states;
+ auto possibleStates = reinterpret_cast<state_effecter_possible_states*>(
+ possibleStatesPtr);
+ possibleStates->state_set_id = PLDM_OEM_IBM_PCIE_SLOT_EFFECTER_STATE;
+ possibleStates->possible_states_size = 2;
+ auto state =
+ reinterpret_cast<state_effecter_possible_states*>(possibleStates);
+ state->states[0].byte = 14;
+ pldm::responder::pdr_utils::PdrEntry pdrEntry{};
+ pdrEntry.data = entry.data();
+ pdrEntry.size = pdrSize;
+ repo.addRecord(pdrEntry);
+ }
+}
+
void buildAllCodeUpdateSensorPDR(oem_ibm_platform::Handler* platformHandler,
uint16_t entityType, uint16_t entityInstance,
uint16_t stateSetID, pdr_utils::Repo& repo)
@@ -255,6 +343,66 @@
repo.addRecord(pdrEntry);
}
+void buildAllSlotEnableSensorPDR(oem_ibm_platform::Handler* platformHandler,
+ pdr_utils::Repo& repo,
+ const std::vector<std::string>& slotobjpaths)
+{
+ size_t pdrSize = 0;
+ pdrSize = sizeof(pldm_state_sensor_pdr) +
+ sizeof(state_sensor_possible_states);
+ std::vector<uint8_t> entry{};
+ entry.resize(pdrSize);
+ pldm_state_sensor_pdr* pdr =
+ reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
+ if (!pdr)
+ {
+ error("Failed to get record by PDR type, ERROR:{ERR}", "ERR", lg2::hex,
+ static_cast<unsigned>(PLDM_PLATFORM_INVALID_SENSOR_ID));
+ return;
+ }
+ auto& associatedEntityMap = platformHandler->getAssociateEntityMap();
+ for (const auto& entity_path : slotobjpaths)
+ {
+ pdr->hdr.record_handle = 0;
+ pdr->hdr.version = 1;
+ pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
+ pdr->hdr.record_change_num = 0;
+ pdr->hdr.length = sizeof(pldm_state_sensor_pdr) - sizeof(pldm_pdr_hdr);
+ pdr->terminus_handle = TERMINUS_HANDLE;
+ pdr->sensor_id = platformHandler->getNextSensorId();
+ if (entity_path != "" && associatedEntityMap.contains(entity_path))
+ {
+ pdr->entity_type = associatedEntityMap.at(entity_path).entity_type;
+ pdr->entity_instance =
+ associatedEntityMap.at(entity_path).entity_instance_num;
+ pdr->container_id =
+ associatedEntityMap.at(entity_path).entity_container_id;
+ }
+ else
+ {
+ // the slots are not present, dont create the PDR
+ continue;
+ }
+
+ pdr->sensor_init = PLDM_NO_INIT;
+ pdr->sensor_auxiliary_names_pdr = false;
+ pdr->composite_sensor_count = 1;
+
+ auto* possibleStatesPtr = pdr->possible_states;
+ auto possibleStates =
+ reinterpret_cast<state_sensor_possible_states*>(possibleStatesPtr);
+ possibleStates->state_set_id = PLDM_OEM_IBM_PCIE_SLOT_SENSOR_STATE;
+ possibleStates->possible_states_size = 1;
+ auto state =
+ reinterpret_cast<state_sensor_possible_states*>(possibleStates);
+ state->states[0].byte = 15;
+ pldm::responder::pdr_utils::PdrEntry pdrEntry{};
+ pdrEntry.data = entry.data();
+ pdrEntry.size = pdrSize;
+ repo.addRecord(pdrEntry);
+ }
+}
+
void pldm::responder::oem_ibm_platform::Handler::buildOEMPDR(
pdr_utils::Repo& repo)
{
@@ -271,6 +419,13 @@
ENTITY_INSTANCE_1,
PLDM_OEM_IBM_SYSTEM_POWER_STATE, repo);
+ static constexpr auto objectPath = "/xyz/openbmc_project/inventory/system";
+ const std::vector<std::string> slotInterface = {
+ "xyz.openbmc_project.Inventory.Item.PCIeSlot"};
+ auto slotPaths = dBusIntf->getSubTreePaths(objectPath, 0, slotInterface);
+ buildAllSlotEnableEffecterPDR(this, repo, slotPaths);
+ buildAllSlotEnableSensorPDR(this, repo, slotPaths);
+
buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
ENTITY_INSTANCE_0, PLDM_OEM_IBM_BOOT_STATE,
repo);