summaryrefslogtreecommitdiffstats
path: root/src/usr/ipmi
diff options
context:
space:
mode:
authorAndrew Jeffery <andrewrj@au1.ibm.com>2018-09-28 14:48:58 +0930
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-10-10 13:39:41 -0500
commit5fc457309f2c6bad2bf1464a4cc7756692ede3b8 (patch)
treef7a1190a397d8fe77cd232548f5e8615c0dedab4 /src/usr/ipmi
parent1b481183921d9877a5693219249bb9c4cd8ccf69 (diff)
downloadtalos-hostboot-5fc457309f2c6bad2bf1464a4cc7756692ede3b8.tar.gz
talos-hostboot-5fc457309f2c6bad2bf1464a4cc7756692ede3b8.zip
ipmi: Split into ipmibase and ipmiext modules
Split the IPMI module into base and ext portions, with the BT interface, device driver and resource provider in the base portion, and all remaining IPMI functionality in the ext portion. The split is in preparation for moving the base functionality in the hostboot base image. Change-Id: Iec864f96240d79f4fadd5519d2ef46437d07c1fd Signed-off-by: Andrew Jeffery <andrewrj@au1.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/66792 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Corey V. Swenson <cswenson@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/ipmi')
-rw-r--r--src/usr/ipmi/HBconfig16
-rw-r--r--src/usr/ipmi/ipmi.mk29
-rw-r--r--src/usr/ipmi/ipmibt.C399
-rw-r--r--src/usr/ipmi/ipmibt.H184
-rw-r--r--src/usr/ipmi/ipmichassiscontrol.C86
-rw-r--r--src/usr/ipmi/ipmiconfig.C45
-rw-r--r--src/usr/ipmi/ipmiconfig.H55
-rw-r--r--src/usr/ipmi/ipmiconfiglookup.C467
-rw-r--r--src/usr/ipmi/ipmidcmi.C148
-rw-r--r--src/usr/ipmi/ipmidd.C436
-rw-r--r--src/usr/ipmi/ipmidd.H174
-rw-r--r--src/usr/ipmi/ipmifru.C356
-rw-r--r--src/usr/ipmi/ipmifru.H127
-rw-r--r--src/usr/ipmi/ipmifruinv.C2300
-rw-r--r--src/usr/ipmi/ipmifruinvprvt.H689
-rw-r--r--src/usr/ipmi/ipmimsg.C69
-rw-r--r--src/usr/ipmi/ipmimsg.H133
-rw-r--r--src/usr/ipmi/ipmipowerstate.C86
-rw-r--r--src/usr/ipmi/ipmirp.C1140
-rw-r--r--src/usr/ipmi/ipmirp.H284
-rw-r--r--src/usr/ipmi/ipmisel.C596
-rw-r--r--src/usr/ipmi/ipmiselrecord.C54
-rw-r--r--src/usr/ipmi/ipmisensor.C1763
-rw-r--r--src/usr/ipmi/ipmiwatchdog.C204
-rw-r--r--src/usr/ipmi/makefile46
-rw-r--r--src/usr/ipmi/runtime/makefile38
-rw-r--r--src/usr/ipmi/runtime/rt_ipmirp.C190
-rw-r--r--src/usr/ipmi/runtime/test/makefile31
-rw-r--r--src/usr/ipmi/runtime/test/rt_ipmitest.H102
29 files changed, 0 insertions, 10247 deletions
diff --git a/src/usr/ipmi/HBconfig b/src/usr/ipmi/HBconfig
deleted file mode 100644
index f0c4281f9..000000000
--- a/src/usr/ipmi/HBconfig
+++ /dev/null
@@ -1,16 +0,0 @@
-config BMC_IPMI
- default y if BMC_BT_LPC_IPMI
- help
- Determines if Hostboot communicates to the BMC using IPMI
-
-config BMC_BT_LPC_IPMI
- default n
- depends on BMC_IPMI
- help
- Determines if the BMC uses the LPC bus for block-transfer IPMI traffic
-
-config BMC_IPMI_LONG_WATCHDOG
- default y if CONSOLE_OUTPUT_TRACE || CONSOLE_TRACE_LITE
- depends on BMC_IPMI
- help
- Sets watchdog default timer to several times normal for debugging
diff --git a/src/usr/ipmi/ipmi.mk b/src/usr/ipmi/ipmi.mk
deleted file mode 100644
index 9e4459543..000000000
--- a/src/usr/ipmi/ipmi.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/usr/ipmi/ipmi.mk $
-#
-# OpenPOWER HostBoot Project
-#
-# Contributors Listed Below - COPYRIGHT 2015,2017
-# [+] International Business Machines Corp.
-#
-#
-# 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.
-#
-# IBM_PROLOG_END_TAG
-# common objects between hostboot and runtime hostboot
-OBJS += ipmisel.o
-OBJS += ipmisensor.o
-OBJS += ipmidcmi.o
-OBJS += ipmiconfiglookup.o
diff --git a/src/usr/ipmi/ipmibt.C b/src/usr/ipmi/ipmibt.C
deleted file mode 100644
index 818813d79..000000000
--- a/src/usr/ipmi/ipmibt.C
+++ /dev/null
@@ -1,399 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmibt.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file ipmibt.C
- * @brief code for the IPMI BT message class
- */
-
-#include <devicefw/driverif.H>
-#include <devicefw/userif.H>
-#include <ipmi/ipmi_reasoncodes.H>
-#include <errl/errlmanager.H>
-
-#include <util/lockfree/counter.H>
-
-#include "ipmibt.H"
-#include "ipmirp.H"
-#include <ipmi/ipmiif.H>
-#include <errno.h>
-#include <config.h>
-
-// Defined in ipmidd.C
-extern trace_desc_t * g_trac_ipmi;
-#define IPMI_TRAC(printf_string,args...) \
- TRACFCOMP(g_trac_ipmi,"bt: " printf_string,##args)
-
-namespace IPMI
-{
- ///
- /// @brief msg ctor
- /// @param[in] i_cmd, the network function & command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (new'd space)
- ///
- BTMessage::BTMessage(const command_t& i_cmd, const uint8_t i_len,
- uint8_t* i_data):
- Message(i_cmd, i_len, i_data)
- {
- // Sometimes we need to get back to this IPMI msg from the msg_t,
- // and sometimes we need to get the msg_t from the IPMI msg. So they
- // know about each other.
- iv_msg->extra_data = static_cast<void*>(this);
- iv_msg->type = MSG_STATE_SEND;
- }
-
- ///
- /// @brief Transimit - send the data out the device interface
- ///
- errlHndl_t BTMessage::phy_xmit(void)
- {
- // When a uint8_t is constructed, it's initialied to 0. So,
- // this initializes the sequence counter to 0.
- static Util::Lockfree::Counter<uint8_t> seq;
-
- // Assign a "unique" sequence number. Note that we don't
- // leverage the network function to create a sequence
- // number, we just keep an 8 bit counter. This *should*
- // be ok - it means we will get back the response to any
- // particular message before we send another 254 messages.
- // This seems safe.
- iv_seq = seq.next();
-
- // Initialize the error state of the message
- iv_state = 0;
-
- size_t unused_size;
- errlHndl_t err = deviceOp(DeviceFW::WRITE,
- TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
- static_cast<void*>(this),
- unused_size,
- DeviceFW::IPMIBT);
-
- // If we're not going to remain on the i_sendq, we need to delete
- // the data.
- if ((err) || (iv_state != EAGAIN))
- {
- delete[] iv_data;
- iv_data = NULL;
- }
-
- if (!err)
- {
- // If there wasn't an error, and we don't see EAGAIN, we need to
- // queue up for a response. Note we queue up both synchronus and
- // asynchronous messages, and let the subclasses handle what
- // happens when the response arrives (because it will.)
- if (iv_state != EAGAIN)
- {
- Singleton<IpmiRP>::instance().queueForResponse(*this);
- }
-
- // Otherwise we had no error, but were told EAGAIN, which means the
- // interface was busy.
- else
- {
- IPMI_TRAC(INFO_MRK "busy, queue head %x:%x", iv_netfun, iv_cmd);
- }
- }
-
- return err;
- }
-
- ///
- /// @brief Receive - get bits off the block-transfer interface
- ///
- errlHndl_t BTMessage::recv(void)
- {
- // Check to make sure we are in the right state (coding error)
- assert(iv_data == NULL);
-
- // Go down to the device and read. Note the driver is BT specific
- // and we're BT specific so we can send down a BTMessage object.
- size_t unused_length;
- errlHndl_t err = deviceOp(DeviceFW::READ,
- TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
- static_cast<void*>(this),
- unused_length,
- DeviceFW::IPMIBT);
- if (err)
- {
- delete[] iv_data;
-
- // If the reading the response fails, the caller may still call
- // delete[] on the pointer we return to them. This makes sure that
- // for this case, they're just deleting NULL.
- iv_data = NULL;
- iv_len = 0;
- }
-
- // For BT messages, the sequence number is the key - for other xports
- // it might be different. Note the sequence number is a reference to
- // our base's iv_key, so we're done.
- return err;
- }
-
- ///
- /// @brief BTSyncMessage ctor
- /// @param[in] i_cmd, the network function & command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (new'd space)
- ///
- BTSyncMessage::BTSyncMessage(const command_t& i_cmd,
- const uint8_t i_len,
- uint8_t* i_data):
- BTMessage(i_cmd, i_len, i_data)
- {
- }
-
- ///
- /// @brief BTAsyncMessage ctor
- /// @param[in] i_cmd, the network function & command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (new'd space)
- ///
- BTAsyncMessage::BTAsyncMessage(const command_t& i_cmd,
- const uint8_t i_len,
- uint8_t* i_data):
- BTMessage(i_cmd, i_len, i_data)
- {
- }
-
- ///
- /// @brief BTAsyncReadEventMessage ctor
- /// @param[in] i_cmd, the network function & command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (new'd space)
- ///
- BTAsyncReadEventMessage::BTAsyncReadEventMessage(const command_t& i_cmd,
- const uint8_t i_len,
- uint8_t* i_data):
- BTAsyncMessage(i_cmd, i_len, i_data)
- {
- }
-
- ///
- /// @brief sync msg transmit
- ///
- bool BTSyncMessage::xmit(void)
- {
- errlHndl_t err = BTMessage::phy_xmit();
-
- if (err)
- {
- // Something went wrong, so we need to respond back with the error
- iv_errl = err;
-
- msg_q_t mq = Singleton<IpmiRP>::instance().msgQueue();
- int rc = msg_respond(mq, iv_msg);
- if (rc)
- {
- // Yuk. We can't respond back to our caller with that error. So,
- // we'll commit it. I don't see much sense in creating another
- // error log, so we'll just trace the msg_respond() failure.
- IPMI_TRAC(ERR_MRK "msg_respond() i/o error (transmit) %d", rc);
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
- iv_errl = NULL;
- }
- }
-
- // If we had an i/o error we want the idle loop to stop
- // If we got EAGAIN we want the idle loop to stop as we just
- // put a message on the queue which couldn't be sent.
- return (iv_state != 0);
- }
-
- ///
- /// @brief async msg transmit
- ///
- bool BTAsyncMessage::xmit(void)
- {
- errlHndl_t err = BTMessage::phy_xmit();
-
- if (err)
- {
- // Not much we're going to do here, so just commit the error.
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
- }
-
- // If we had an i/o error we want the idle loop to stop.
- // If we got EAGAIN we want the idle loop to stop as we just
- // put a message on the queue which couldn't be sent.
- return (iv_state != 0);
- }
-
- ///
- /// @brief sync handle response
- ///
- void BTSyncMessage::response(msg_q_t i_msgQ)
- {
- // Send the response to the original caller of sendrecv()
- int rc = msg_respond(i_msgQ, iv_msg);
- if (rc)
- {
- // Not much we're going to do here, so lets commit an error and
- // the original request will timeout.
- IPMI_TRAC(ERR_MRK "msg_respond() i/o error (response) %d", rc);
-
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISRV_REPLY
- * @reasoncode IPMI::RC_INVALID_QRESPONSE
- * @userdata1 rc from msg_respond()
- * @devdesc msg_respond() failed
- * @custdesc Firmware error during system boot
- */
- errlHndl_t err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISRV_REPLY,
- IPMI::RC_INVALID_QRESPONSE,
- rc,
- 0,
- true);
-
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
-
- // Frotz the response data
- delete[] iv_data;
- iv_data = NULL;
- }
- }
-
- ///
- /// @brief async msg response
- ///
- void BTAsyncMessage::response(msg_q_t)
- {
- // If our completion code isn't CC_OK, lets log that fact. There's
- // not much we can do, but at least this might give a hint that
- // something is awry. Note the caller doesn't care, or this would
- // be synchronous.
- if (iv_cc != IPMI::CC_OK)
- {
- IPMI_TRAC(ERR_MRK "async message (%x:%x seq %d) completion code %x",
- iv_netfun, iv_cmd, iv_seq, iv_cc);
- }
-
- // Yes, this is OK - there is no further reference to this object.
- delete this;
- }
-
- ///
- /// @brief handle the read of an event (OEM SEL)
- ///
- void BTAsyncReadEventMessage::response(msg_q_t)
- {
- do {
- // If our completion code isn't CC_OK, lets log that fact. There's
- // not much we can do, but at least this might give a hint that
- // something is awry.
- if (iv_cc != IPMI::CC_OK)
- {
- IPMI_TRAC(ERR_MRK "read event message (%x:%x seq %d) "
- "completion code %x",
- iv_netfun, iv_cmd, iv_seq, iv_cc);
-
- if (iv_cc == IPMI::CC_CMDSPC1)
- {
- // We got a completion code with 0x80, which is no data
- // Let's trace the event, but not log an error.
- IPMI_TRAC(ERR_MRK "SEL returned with no data, not logging "
- "an error");
- break;
- }
-
- /*@
- * @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid IPMI::MOD_IPMISRV_REPLY
- * @reasoncode IPMI::RC_READ_EVENT_FAILURE
- * @userdata1 command of message
- * @userdata2 completion code
- * @devdesc an async completion code was not CC_OK
- * @custdesc Unexpected IPMI completion code from the BMC
- */
- errlHndl_t err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_INFORMATIONAL,
- IPMI::MOD_IPMISRV_REPLY,
- IPMI::RC_READ_EVENT_FAILURE,
- iv_cmd,
- iv_cc,
- true);
-
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
- break;
- }
-
- // Before we self destruct, we need to turn the data collected in to
- // a record we can pass to the waiting event handler.
- Singleton<IpmiRP>::instance().postEvent(new IPMI::oemSEL(iv_data));
-
- } while(false);
-
- // Yes, this is OK - there is no further reference to this object.
- delete this;
- }
-
- ///
- /// @brief static factory
- ///
- /// Implement the factory member in terms of the BT interface. This is done
- /// in each of the back-end implementations, only one of which should be
- /// configured in at build time.
- ///
- /// @param[in] i_cmd, the network function & command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (allocated space)
- /// @param[in] i_type, synchronous or async
- ///
- /// @return a pointer to a new'd Message object
- ///
- Message* Message::factory(const command_t& i_cmd, const uint8_t i_len,
- uint8_t* i_data, const message_type i_type)
- {
- Message* new_message = NULL;
-
- switch(i_type)
- {
- case TYPE_SYNC:
- new_message = new BTSyncMessage(i_cmd, i_len, i_data);
- break;
- case TYPE_ASYNC:
- new_message = new BTAsyncMessage(i_cmd, i_len, i_data);
- break;
- case TYPE_EVENT:
- new_message = new BTAsyncReadEventMessage(i_cmd, i_len, i_data);
- break;
- default:
- // We have ourselves a bug
- assert(false, "ipmi message factory: unk type %d\n", i_type);
- break;
- }
-
- return new_message;
- }
-};
diff --git a/src/usr/ipmi/ipmibt.H b/src/usr/ipmi/ipmibt.H
deleted file mode 100644
index 0a757707a..000000000
--- a/src/usr/ipmi/ipmibt.H
+++ /dev/null
@@ -1,184 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmibt.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2015 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-#ifndef __IPMI_IPMIBT_H
-#define __IPMI_IPMIBT_H
-
-#include "ipmimsg.H"
-
-/// So, IPMI_BT_MAX_DATA == BMC receive size - IPMI_BT_HEADER_SIZE;
-#define IPMI_BT_HEADER_SIZE 3
-
-namespace IPMI
-{
- // IPMI block-transfer message base class
- class BTMessage : public Message
- {
- public:
- ///
- /// @brief msg ctor
- /// @param[in] i_cmd, the network function & command
- /// @param[in] i_data, the data for the command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (new'd space)
- ///
- BTMessage(const command_t& i_cmd = no_command(),
- const uint8_t i_len = 0,
- uint8_t* i_data = NULL);
-
- virtual ~BTMessage(void)
- {}
-
- ///
- /// @brief transmit a message.
- /// @return Error from operation
- ///
- errlHndl_t phy_xmit(void);
-
- ///
- /// @brief transmit a message.
- /// @return true iff there was no transmission error
- ///
- /// @note we're not pure abstract as we want to be able to
- /// instantiate an object of BTMessage for reading.
- ///
- virtual bool xmit(void)
- {return true;}
-
- ///
- /// @brief receive a message.
- ///
- errlHndl_t recv(void);
-
- ///
- /// @brief complete the processing when a response arrives
- /// @param[in] i_msgQ, the resource providers message queue
- /// @return void
- /// @note we're not pure abstract as we want to be able to
- /// instantiate an object of BTMessage for reading.
- ///
- virtual void response(msg_q_t i_msgQ)
- {return;}
-
- ///
- /// @brief the size of the BT header
- /// @param void
- /// @return size_t, the header size
- /// @note IPMI_BT_MAX_DATA == BMC receive size - IPMI_BT_HEADER_SIZE;
- ///
- size_t header_size(void)
- { return IPMI_BT_HEADER_SIZE; }
- };
-
- // IPMI BT synchronous message
- class BTSyncMessage : public BTMessage
- {
- public:
- ///
- /// @brief BTSyncMessage ctor
- /// @param[in] i_cmd, the network function & command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (new'd space)
- ///
- BTSyncMessage(const command_t& i_cmd,
- const uint8_t i_len, uint8_t* i_data);
-
- ///
- /// @brief transmit a message.
- ///
- /// @return true iff there was no transmission error
- ///
- bool xmit(void);
-
- ///
- /// @brief complete the processing when a response arrives
- /// @param[in] i_msgQ, the resource providers message queue
- /// @return void
- ///
- void response(msg_q_t i_msgQ);
-
- };
-
- // IPMI BT asynchronous message
- class BTAsyncMessage : public BTMessage
- {
- public:
- ///
- /// @brief BTSyncMessage ctor
- /// @param[in] i_cmd, the network function & command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (new'd space)
- ///
- BTAsyncMessage(const command_t& i_cmd,
- const uint8_t i_len, uint8_t* i_data);
-
- ///
- /// @brief BTSyncMessage dtor
- ///
- virtual ~BTAsyncMessage(void)
- { delete[] iv_data; }
-
- ///
- /// @brief transmit a message.
- ///
- /// @return true iff there was no transmission error
- ///
- bool xmit(void);
-
- ///
- /// @brief complete the processing when a response arrives
- /// @param[in] i_msgQ, the resource providers message queue
- /// @return void
- ///
- void response(msg_q_t i_msgQ);
- };
-
- // IPMI BT asynchronous read event message. Reading events is sort
- // of an asynch message; we fire the request from the resource
- // provider thread (so we don't want to wait.) The response is
- // special in that we don't just delete ourselves, but rather turn
- // the response (OEM SEL) into a message for an event handler.
- class BTAsyncReadEventMessage : public BTAsyncMessage
- {
- public:
- ///
- /// @brief BTASyncReadEventMessage ctor
- /// @param[in] i_cmd, the network function & command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (new'd space)
- ///
- BTAsyncReadEventMessage(const command_t& i_cmd,
- const uint8_t i_len, uint8_t* i_data);
-
- ///
- /// @brief complete the processing when a response arrives
- /// @param[in] i_msgQ, the resource providers message queue
- /// @return void
- ///
- void response(msg_q_t i_msgQ);
- };
-
-}; // end namespace IPMI
-
-#endif
diff --git a/src/usr/ipmi/ipmichassiscontrol.C b/src/usr/ipmi/ipmichassiscontrol.C
deleted file mode 100644
index ff4161e25..000000000
--- a/src/usr/ipmi/ipmichassiscontrol.C
+++ /dev/null
@@ -1,86 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmichassiscontrol.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2016 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file ipmichassiscontrol.C
- *
- * Ipmi send chassis control command
- *
- */
-
-/******************************************************************************/
-// Includes
-/******************************************************************************/
-#include <stdint.h>
-#include <errl/errlentry.H>
-#include <ipmi/ipmichassiscontrol.H>
-#include <ipmi/ipmiif.H>
-#include <initservice/istepdispatcherif.H>
-
-/******************************************************************************/
-// Globals/Constants
-/******************************************************************************/
-// Defined in ipmidd.C
-extern trace_desc_t * g_trac_ipmi;
-#define IPMI_TRAC(printf_string,args...) \
- TRACFCOMP(g_trac_ipmi,"cc: " printf_string,##args)
-
-namespace IPMI
-{
-
-/******************************************************************************/
-// Functions
-/******************************************************************************/
-
-errlHndl_t chassisControl(const uint8_t i_chassisControlState )
-{
- errlHndl_t err_ipmi = NULL;
-
- size_t len = 1; // IPMI spec has request data at 1 bytes
-
- //create request data buffer
- uint8_t* data = new uint8_t[len];
-
- IPMI::completion_code cc = IPMI::CC_UNKBAD;
-
- data[0] = i_chassisControlState;
-
- err_ipmi = IPMI::sendrecv(IPMI::chassis_power_off(), cc, len, data);
-
- //cleanup buffer
- delete[] data;
-
- if(cc != IPMI::CC_OK)
- {
- IPMI_TRAC("Chassis control : BMC returned not ok CC[%x]",cc);
- }
-
- // power off command has been sent to the BMC, tell the istep dispacher to
- // stop executing steps.
- INITSERVICE::stopIpl();
-
- return err_ipmi;
-}
-} // namespace
-
diff --git a/src/usr/ipmi/ipmiconfig.C b/src/usr/ipmi/ipmiconfig.C
deleted file mode 100644
index cdfb1167b..000000000
--- a/src/usr/ipmi/ipmiconfig.C
+++ /dev/null
@@ -1,45 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmiconfig.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2015 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-#include <stdint.h>
-#include "ipmiconfig.H"
-
- //
- // Information contained in the Get Interface Capabilities command
- //
- // Request to response time default, in seconds
-const uint8_t IPMI::g_bmc_timeout = 5;
-
- // Number of allowed outstanding requests default
-const uint8_t IPMI::g_outstanding_req = 0x01;
-
- // The size of the BMC input buffer default (our write)
-const uint8_t IPMI::g_xmit_buffer_size = 0x40;
-
- // The size of the BMC transmit buffer default (our read)
-const uint8_t IPMI::g_recv_buffer_size = 0x40;
-
- // How many times we should retry a message if the BMC timesout default
-const uint8_t IPMI::g_retries = 0x00;
diff --git a/src/usr/ipmi/ipmiconfig.H b/src/usr/ipmi/ipmiconfig.H
deleted file mode 100644
index 673be6128..000000000
--- a/src/usr/ipmi/ipmiconfig.H
+++ /dev/null
@@ -1,55 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmiconfig.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2014 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-#ifndef __IPMI_IPMICONFIG_H
-#define __IPMI_IMPICONFIG_H
-
-/**
- * @file ipmiconfig.H
- * @brief IPMI service provider defaults and constants
- */
-
-namespace IPMI
-{
- //
- // Information contained in the Get Interface Capabilities command
- //
- // Request to response time default, in seconds
- extern const uint8_t g_bmc_timeout;
-
- // Number of allowed outstanding requests default
- extern const uint8_t g_outstanding_req;
-
- // The size of the BMC input buffer default (our write)
- extern const uint8_t g_xmit_buffer_size;
-
- // The size of the BMC transmit buffer default (our read)
- extern const uint8_t g_recv_buffer_size;
-
- // How many times we should retry a message if the BMC timesout default
- extern const uint8_t g_retries;
-};
-
-#endif
diff --git a/src/usr/ipmi/ipmiconfiglookup.C b/src/usr/ipmi/ipmiconfiglookup.C
deleted file mode 100644
index ee2eb85eb..000000000
--- a/src/usr/ipmi/ipmiconfiglookup.C
+++ /dev/null
@@ -1,467 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmiconfiglookup.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-#include <ipmi/ipmiconfiglookup.H>
-
-#include <algorithm>
-#include <assert.h>
-
-#include <attributeenums.H>
-#include <ipmi/ipmi_reasoncodes.H>
-#include <targeting/targplatutil.H>
-#include <targeting/common/targetservice.H>
-
-extern trace_desc_t * g_trac_ipmi;
-
-namespace IPMI
-{
-
-//-----------------------------------------------------------------------------
-// Private method used to lookup sensor information from the IPMI_SENSOR_ARRAY
-// attribute of the i_target parameter.
-//
-// Returns true if the sensor was found, false otherwise.
-//-----------------------------------------------------------------------------
-bool IpmiConfigLookup::lookupIPMISensorInfo(TARGETING::Target * i_target,
- uint32_t i_sensorNumber,
- uint8_t& o_sensorType,
- uint8_t& o_entityId,
- TARGETING::SENSOR_NAME& o_sensorName
- )
-{
- using IPMI_ARRAY_ELEMENT = uint16_t[2];
- bool l_result{false};
-
- assert(nullptr != i_target);
- assert(TARGETING::UTIL::INVALID_IPMI_SENSOR != i_sensorNumber);
-
- //Get the IPMI_SENSOR_ARRAY attribute from i_target.
- TARGETING::AttributeTraits<TARGETING::ATTR_IPMI_SENSORS>::Type l_ipmiArray;
- if(!i_target->tryGetAttr<TARGETING::ATTR_IPMI_SENSORS>(l_ipmiArray))
- {
- return l_result;
- }
-
- //Search the IPMI_SENSOR_ARRAY for the desired sensor.
- uint32_t elementCount = (sizeof(l_ipmiArray)/sizeof(l_ipmiArray[0]));
- const IPMI_ARRAY_ELEMENT * begin = &l_ipmiArray[0];
- const IPMI_ARRAY_ELEMENT * end = &l_ipmiArray[elementCount];
- const IPMI_ARRAY_ELEMENT * itr{nullptr};
-
- itr = std::find_if(begin,
- end,
- [i_sensorNumber] (const IPMI_ARRAY_ELEMENT& a)
- {
- return a[TARGETING::IPMI_SENSOR_ARRAY_NUMBER_OFFSET]
- == i_sensorNumber;
- }
- );
-
- if(itr != end)
- {
- l_result = true;
- uint16_t l_sensorName = (*itr)
- [TARGETING::IPMI_SENSOR_ARRAY_NAME_OFFSET];
- o_sensorName = static_cast<TARGETING::SENSOR_NAME>(l_sensorName);
- o_sensorType = static_cast<uint8_t>((l_sensorName >> 8) & 0x00FF);
- o_entityId = static_cast<uint8_t>(l_sensorName & 0x00FF);
- }
-
- return l_result;
-}
-
-
-//-----------------------------------------------------------------------------
-// Private method used to lookup sensor information from the GPU_SENSORS
-// array attribute of the i_target parameter.
-//
-// Returns true if the sensor was found, false otherwise.
-//-----------------------------------------------------------------------------
-bool IpmiConfigLookup::lookupGPUSensorInfo(TARGETING::Target * i_target,
- uint32_t i_sensorNumber,
- uint8_t& o_sensorType,
- uint8_t& o_entityId,
- TARGETING::SENSOR_NAME& o_sensorName
- )
-{
- using GPU_ARRAY_ELEMENT = uint16_t[7];
- bool l_result{false};
-
- assert(nullptr != i_target);
- assert(TARGETING::UTIL::INVALID_IPMI_SENSOR != i_sensorNumber);
-
- // Get the GPU_SENSORS array attribute from i_target
- TARGETING::AttributeTraits<TARGETING::ATTR_GPU_SENSORS>::Type
- l_sensorArray;
- if(!i_target->tryGetAttr<TARGETING::ATTR_GPU_SENSORS>(l_sensorArray))
- {
- return l_result;
- }
-
- //Search the sensor array for the desired sensor
- uint32_t elementCount = (sizeof(l_sensorArray)/sizeof(l_sensorArray[0]));
- const GPU_ARRAY_ELEMENT * begin = &l_sensorArray[0];
- const GPU_ARRAY_ELEMENT * end = &l_sensorArray[elementCount];
- const GPU_ARRAY_ELEMENT * itr{nullptr};
-
- itr = std::find_if(begin,
- end,
- [i_sensorNumber] (const GPU_ARRAY_ELEMENT& a)
- {
- return (
- (a[TARGETING::GPU_SENSOR_ARRAY_FUNC_ID_OFFSET] == i_sensorNumber) ||
- (a[TARGETING::GPU_SENSOR_ARRAY_TEMP_ID_OFFSET] == i_sensorNumber) ||
- (a[TARGETING::GPU_SENSOR_ARRAY_MEM_TEMP_ID_OFFSET] == i_sensorNumber));
- }
- );
-
- if(itr != end)
- {
- l_result = true;
- uint16_t l_sensorName;
- if (*itr[TARGETING::GPU_SENSOR_ARRAY_FUNC_ID_OFFSET] == i_sensorNumber)
- {
- l_sensorName = *itr[TARGETING::GPU_SENSOR_ARRAY_FUNC_OFFSET];
- }
- else if
- (*itr[TARGETING::GPU_SENSOR_ARRAY_TEMP_ID_OFFSET] == i_sensorNumber)
- {
- l_sensorName = *itr[TARGETING::GPU_SENSOR_ARRAY_TEMP_ID_OFFSET];
- }
- else
- {
- l_sensorName = *itr[TARGETING::GPU_SENSOR_ARRAY_MEM_TEMP_ID_OFFSET];
- }
-
- o_sensorName = static_cast<TARGETING::SENSOR_NAME>(l_sensorName);
- o_sensorType = static_cast<uint8_t>((l_sensorName >> 8) & 0x00FF);
- o_entityId = static_cast<uint8_t>(l_sensorName & 0x00FF);
- }
-
- return l_result;
-}
-
-//--------------------------------------------------------------------------
-//Given a sensor number, lookup and parse SENSOR_NAME into SENSOR_TYPE
-//and ENTITY_ID values.
-//--------------------------------------------------------------------------
-bool IpmiConfigLookup::getIPMISensorInfo(uint32_t i_sensorNumber,
- uint8_t * o_sensorType,
- uint8_t * o_entityId,
- TARGETING::SENSOR_NAME * o_sensorName,
- TARGETING::Target * i_sensorTarget
- )
-{
- bool l_result{false};
-
- //Ensure that the sensor number is not the invalid id.
- assert(TARGETING::UTIL::INVALID_IPMI_SENSOR != i_sensorNumber);
-
- TARGETING::SENSOR_NAME l_sensorName =
- static_cast<TARGETING::SENSOR_NAME>(0);
- uint8_t l_sensorType = TARGETING::SENSOR_TYPE_NA;
- uint8_t l_entityId = TARGETING::ENTITY_ID_NA;
-
- //Ensure that at least one optional out parameter was given.
- assert(nullptr != o_sensorType ||
- nullptr != o_sensorName ||
- nullptr != o_entityId);
-
- //If the caller passed in a target then find sensor data within the
- //context of the passed in target.
- if(i_sensorTarget)
- {
- if(doesTargetHaveIpmiSensorAttr(i_sensorTarget))
- {
- l_result = lookupIPMISensorInfo(i_sensorTarget,
- i_sensorNumber,
- l_sensorType,
- l_entityId,
- l_sensorName);
- }
- }
- else
- {
- //The caller did not supply a target context for the sensor.
- //Search for the sensor amoung all targets.
- for(auto itr = TARGETING::targetService().begin();
- itr != TARGETING::targetService().end(); ++itr)
- {
- if(doesTargetHaveIpmiSensorAttr(*itr))
- {
- l_result = lookupIPMISensorInfo((*itr),
- i_sensorNumber,
- l_sensorType,
- l_entityId,
- l_sensorName);
- if(l_result)
- {
- break;
- }
- }
- else if (doesTargetHaveGPUSensorsAttr(*itr))
- {
- l_result = lookupGPUSensorInfo((*itr),
- i_sensorNumber,
- l_sensorType,
- l_entityId,
- l_sensorName);
- if (l_result)
- {
- break;
- }
-
- }
- }
- }
-
- //set any out parameters that are desired by the caller.
- if(o_sensorName)
- {
- *o_sensorName = l_sensorName;
- }
-
- if(o_sensorType)
- {
- *o_sensorType = l_sensorType;
- }
-
- if(o_entityId)
- {
- *o_entityId = l_entityId;
- }
-
- return l_result;
-}
-
-//------------------------------------------------------------------
-errlHndl_t IpmiConfigLookup::getSensorType(uint32_t i_sensorNumber,
- uint8_t & o_sensorType,
- TARGETING::Target * i_sensorTarget
- )
-{
- errlHndl_t l_errl{};
-
- //Ensure that the sensor number is not the invalid id.
- if(TARGETING::UTIL::INVALID_IPMI_SENSOR == i_sensorNumber)
- {
- TRACFCOMP(g_trac_ipmi,
- ERR_MRK"The i_sensorNumber parameter "
- "is the invalid sensor number (%X).",
- i_sensorNumber
- );
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR_TYPE
- * @reasoncode IPMI::RC_INVALID_SENSOR_NUMBER
- * @userdata1 IPMI Sensor Number
- * @userdata2 <unused>
- * @devdesc The passed in sensor number is not valid.
- * @custdesc The passed in sensor number is not valid.
- */
- l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISENSOR_TYPE,
- IPMI::RC_INVALID_SENSOR_NUMBER,
- i_sensorNumber,
- 0,
- false);
- return l_errl;
- }
-
- bool l_rc = getIPMISensorInfo(i_sensorNumber,
- &o_sensorType,
- nullptr,
- nullptr,
- i_sensorTarget
- );
-
- if(!l_rc)
- {
-
- TRACFCOMP(g_trac_ipmi,
- ERR_MRK"Did not find a sensor with number %X.",
- i_sensorNumber);
-
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR_TYPE
- * @reasoncode IPMI::RC_SENSOR_NOT_FOUND
- * @userdata1 IPMI Sensor Number
- * @userdata2 <unused>
- * @devdesc The sensor could not be found based upon
- * the sensor number.
- * @custdesc Unable to determine sensor information.
- */
- l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISENSOR_TYPE,
- IPMI::RC_SENSOR_NOT_FOUND,
- i_sensorNumber,
- 0,
- false);
- }
-
- return l_errl;
-}
-
-//--------------------------------------------------------------------------
-errlHndl_t IpmiConfigLookup::getEntityId(uint32_t i_sensorNumber,
- uint8_t & o_entityId,
- TARGETING::Target * i_sensorTarget
- )
-{
- errlHndl_t l_errl{};
-
- if(TARGETING::UTIL::INVALID_IPMI_SENSOR == i_sensorNumber)
- {
-
- TRACFCOMP(g_trac_ipmi,
- ERR_MRK"The i_sensorNumber parameter "
- "is an invalid sensor number (%X).",
- i_sensorNumber
- );
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR_ENTITY_ID
- * @reasoncode IPMI::RC_INVALID_SENSOR_NUMBER
- * @userdata1 IPMI Sensor Number
- * @userdata2 <unused>
- * @devdesc The passed in sensor number is not valid.
- * @custdesc The passed in sensor number is not valid.
- */
- l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISENSOR_ENTITY_ID,
- IPMI::RC_INVALID_SENSOR_NUMBER,
- i_sensorNumber,
- 0,
- false);
- return l_errl;
- }
-
- bool l_rc = getIPMISensorInfo(i_sensorNumber,
- nullptr,
- &o_entityId,
- nullptr,
- i_sensorTarget
- );
-
- if(!l_rc)
- {
-
- TRACFCOMP(g_trac_ipmi,
- ERR_MRK"Did not find a sensor with number %X.",
- i_sensorNumber);
-
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR_ENTITY_ID
- * @reasoncode IPMI::RC_SENSOR_NOT_FOUND
- * @userdata1 IPMI Sensor Number
- * @userdata2 <unused>
- * @devdesc The sensor could not be found based upon
- * the sensor number.
- * @custdesc Unable to determine sensor information.
- */
- l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISENSOR_ENTITY_ID,
- IPMI::RC_SENSOR_NOT_FOUND,
- i_sensorNumber,
- 0,
- false);
- }
-
- return l_errl;
-}
-
-//-----------------------------------------------------------------------
-errlHndl_t IpmiConfigLookup::getSensorName(uint32_t i_sensorNumber,
- TARGETING::SENSOR_NAME & o_sensorName,
- TARGETING::Target * i_sensorTarget
- )
-{
- errlHndl_t l_errl{};
-
- if(TARGETING::UTIL::INVALID_IPMI_SENSOR == i_sensorNumber)
- {
-
- TRACFCOMP(g_trac_ipmi,
- ERR_MRK"The i_sensorNumber parameter "
- "is an invalid sensor number (%X).",
- i_sensorNumber
- );
-
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR_NAME
- * @reasoncode IPMI::RC_INVALID_SENSOR_NUMBER
- * @userdata1 IPMI Sensor Number
- * @userdata2 <unused>
- * @devdesc The passed in sensor number is not valid.
- * @custdesc The passed in sensor number is not valid.
- */
- l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISENSOR_NAME,
- IPMI::RC_INVALID_SENSOR_NUMBER,
- i_sensorNumber,
- 0,
- false);
- return l_errl;
- }
-
- bool l_rc = getIPMISensorInfo(i_sensorNumber,
- nullptr,
- nullptr,
- &o_sensorName,
- i_sensorTarget
- );
-
- if(!l_rc)
- {
-
- TRACFCOMP(g_trac_ipmi,
- ERR_MRK"Did not find a sensor with number %X.",
- i_sensorNumber);
-
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR_NAME
- * @reasoncode IPMI::RC_SENSOR_NOT_FOUND
- * @userdata1 IPMI Sensor Number
- * @userdata2 <unused>
- * @devdesc The sensor could not be found based upon
- * the sensor number.
- * @custdesc Unable to determine sensor information.
- */
- l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISENSOR_NAME,
- IPMI::RC_SENSOR_NOT_FOUND,
- i_sensorNumber,
- 0,
- false);
- }
-
- return l_errl;
-}
-
-} //End namespace
-
diff --git a/src/usr/ipmi/ipmidcmi.C b/src/usr/ipmi/ipmidcmi.C
deleted file mode 100644
index e3708fdf0..000000000
--- a/src/usr/ipmi/ipmidcmi.C
+++ /dev/null
@@ -1,148 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmidcmi.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file ipmidcmi.C
- * @brief IPMI DCMI command extensions
- */
-
-#include <errl/errlentry.H>
-#include <errl/errlmanager.H>
-#include <ipmi/ipmiif.H>
-#include <ipmi/ipmisensor.H>
-#include <ipmi/ipmi_reasoncodes.H>
-extern trace_desc_t * g_trac_ipmi;
-
-namespace SENSOR
-{
- enum dcmi_cc
- {
- POWER_LIMIT_ACTIVE = 0x00,
- POWER_LIMIT_NOT_ACTIVE = 0x80,
- };
-
- // fetch the user defined power limit stored on the BMC
- // using the DCMI Get Power Limit command
- errlHndl_t getUserPowerLimit( uint16_t &o_powerLimit, bool &o_limitActive )
- {
- o_powerLimit = 0;
-
- // assume the limit has not been activated
- o_limitActive = false;
-
- errlHndl_t l_err = NULL;
-
- // per DCMI spec data size is 3 bytes
- size_t len = 3;
-
- //create request data buffer
- uint8_t* data = new uint8_t[len];
-
- IPMI::completion_code cc = IPMI::CC_UNKBAD;
-
- data[0] = 0xDC; // Group Extension Identification
- data[1] = 0x00; // reserved
- data[2] = 0x00; // reserved
-
- l_err = IPMI::sendrecv(IPMI::get_power_limit(), cc, len, data);
-
- SENSOR::dcmi_cc l_cc = static_cast<SENSOR::dcmi_cc>(cc);
-
- if( l_err == NULL )
- {
- // make sure the completion code is good, then read the bytes
- if( (l_cc == POWER_LIMIT_NOT_ACTIVE) ||
- (l_cc == POWER_LIMIT_ACTIVE) )
- {
- // from the dcmi spec
- // byte 1 completion code
- // byte 2 0xDC
- // byte 3:4 reserved
- // byte 5 exception actions
- // byte 6:7 power limit
- // data[0] is pointing at byte 2 of the dcmi spec description
- // so our offsets will be off by two below
- o_powerLimit = data[5];
- o_powerLimit = ( o_powerLimit << 8 ) + data[4];
-
- // fetch the derating factor from the BMC, then apply it to
- // the value returned in the getPowerLimit command
-
- SENSOR::getSensorReadingData o_sensorData;
-
- // derating factor is held in the system target
- SENSOR::SensorBase(
- TARGETING::SENSOR_NAME_DERATING_FACTOR,
- NULL ).readSensorData( o_sensorData );
-
- // derate the power limit based on the returned value of the
- // sensor - derating factor is returned as a % value and is
- // stored in the event_status field.
- o_powerLimit = ( static_cast<uint64_t>(o_powerLimit) *
- o_sensorData.event_status)/100;
-
- TRACFCOMP(g_trac_ipmi,"Derating factor = %i",o_sensorData.event_status);
- TRACFCOMP(g_trac_ipmi,"Power limit = 0x%i",o_powerLimit);
- TRACFCOMP(g_trac_ipmi,"Power limit is %s", ((cc) ? "not active": "active"));
-
- // the completion code also tells us if the limit is active
- if(l_cc == POWER_LIMIT_ACTIVE )
- {
- o_limitActive = true;
- }
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"bad completion code from BMC=0x%x",cc);
-
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMIDCMI
- * @reasoncode IPMI::RC_DCMI_CMD_FAILED
- * @userdata1 BMC IPMI Completion code.
- * @devdesc Request to get power limit information
- * failed
- * @custdesc The DCMI command to retrieve the power limit
- * data from the BMC has failed, the user
- * defined power limit cannot be applied.
- *
- */
-
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMIDCMI,
- IPMI::RC_DCMI_CMD_FAILED,
- static_cast<uint64_t>(cc),0, true);
-
- l_err->collectTrace(IPMI_COMP_NAME);
-
- }
-
- delete[] data;
- }
-
- return l_err;
- }
-
-}; // end name space
diff --git a/src/usr/ipmi/ipmidd.C b/src/usr/ipmi/ipmidd.C
deleted file mode 100644
index 3462c1a8a..000000000
--- a/src/usr/ipmi/ipmidd.C
+++ /dev/null
@@ -1,436 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmidd.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file ipmidd.C
- *
- * @brief Implementation of the IPMI Device Driver
- */
-
-/*****************************************************************************/
-// I n c l u d e s
-/*****************************************************************************/
-#include <devicefw/driverif.H>
-#include <trace/interface.H>
-#include <errl/errlentry.H>
-#include <errl/errlmanager.H>
-#include <errl/errludlogregister.H>
-#include <errl/errludstring.H>
-#include "ipmidd.H"
-#include <ipmi/ipmiif.H>
-#include <initservice/initserviceif.H>
-#include <util/align.H>
-#include <lpc/lpcif.H>
-#include <config.h>
-
-#include <sys/msg.h>
-#include <errno.h>
-
-#include <sys/time.h>
-#include <sys/task.h>
-
-/*****************************************************************************/
-// D e f i n e s
-/*****************************************************************************/
-
-trace_desc_t* g_trac_ipmi;
-TRAC_INIT(&g_trac_ipmi, IPMI_COMP_NAME, 6*KILOBYTE, TRACE::BUFFER_SLOW);
-
-#define IPMI_TRAC(printf_string,args...) \
- TRACFCOMP(g_trac_ipmi,"dd: " printf_string,##args)
-
-/**
- * @brief Performs an IPMI Message Read Operation
- * This function performs a IPMI Message Read operation. It follows a
- * pre-defined prototype functions in order to be registered with the
- * device-driver framework.
- *
- * @param[in] i_opType Operation type READ
- * @param[in] i_target IPMI target, ignored use the master sentinel
- * @param[out] o_buffer Pointer to a BT message we're going to fill in.
- * @param[out] o_buflen Always sizeof(uint8_t)
- * @param[in] i_accessType DeviceFW::IPMIBT
- * @param[in] i_args This is an argument list for DD framework.
- * In this function, it is unused
- * @return errlHndl_t
- */
-errlHndl_t ddRead(DeviceFW::OperationType i_opType,
- TARGETING::Target* i_target,
- void* o_buffer,
- size_t& o_buflen,
- int64_t i_accessType,
- va_list i_args)
-{
- // If someone passed in the wrong target, we have a coding error
- assert(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL == i_target,
- "ipmi read expects master processor target");
-
- // We are the BT driver, so it's safe to assume they sent us a BTMessage.
- return Singleton<IpmiDD>::instance().receive(
- static_cast<IPMI::BTMessage*>(o_buffer));
-}
-
-/**
- * @brief Performs an IPMI Message Write Operation
- * This function performs a IPMI Message Write operation. It follows a
- * pre-defined prototype functions in order to be registered with the
- * device-driver framework.
- *
- * @param[in] i_opType Operation type WRITE
- * @param[in] i_target IPMI target, ignored use the master sentinel
- * @param[in] i_buffer Pointer to a BT message we're going to transmit
- * @param[in] i_buflen Always sizeof(uint8_t)
- * @param[in] i_accessType DeviceFW::IPMIBT
- * @param[in] i_args This is an argument list for DD framework.
- * In this function, it is unused
- * @return errlHndl_t
- */
-errlHndl_t ddWrite(DeviceFW::OperationType i_opType,
- TARGETING::Target* i_target,
- void* i_buffer,
- size_t& i_buflen,
- int64_t i_accessType,
- va_list i_args)
-{
- // If someone passed in the wrong target, we have a coding error
- assert(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL == i_target,
- "ipmi write expects master processor target");
-
- // We are the BT driver, so it's safe to assume they sent us a BTMessage
- return Singleton<IpmiDD>::instance().send(
- static_cast<IPMI::BTMessage*>(i_buffer));
-}
-
-// Register IPMIDD access functions to DD framework
-DEVICE_REGISTER_ROUTE(DeviceFW::READ,
- DeviceFW::IPMIBT,
- TARGETING::TYPE_PROC,
- ddRead);
-
-DEVICE_REGISTER_ROUTE(DeviceFW::WRITE,
- DeviceFW::IPMIBT,
- TARGETING::TYPE_PROC,
- ddWrite);
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * @brief Read an address from LPC space
- */
-errlHndl_t IpmiDD::readLPC(const uint32_t i_addr, uint8_t& o_data)
-{
- static size_t size = sizeof(uint8_t);
- errlHndl_t err = deviceOp( DeviceFW::READ,
- TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
- static_cast<void*>(&o_data),
- size,
- DEVICE_LPC_ADDRESS(LPC::TRANS_IO, i_addr) );
- return err;
-}
-
-/**
- * @brief Write an address from LPC space
- */
-errlHndl_t IpmiDD::writeLPC(const uint32_t i_addr,
- uint8_t i_data)
-{
- static size_t size = sizeof(uint8_t);
- errlHndl_t err = deviceOp(DeviceFW::WRITE,
- TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
- static_cast<void*>(&i_data),
- size,
- DEVICE_LPC_ADDRESS(LPC::TRANS_IO, i_addr) );
- return err;
-}
-
-/**
- * @brief Static function wrapper to pass into task_create
- */
-static void* poll_control_register( void* /* unused */ )
-{
- IPMI_TRAC(ENTER_MRK "poll_control_register" );
- Singleton<IpmiDD>::instance().pollCtrl();
- return NULL;
-}
-
-/**
- * @brief Poll the control register
- */
-void IpmiDD::pollCtrl(void)
-{
- IPMI_TRAC(ENTER_MRK "poll_control_register" );
-
- // Mark as an independent daemon so if it crashes we terminate.
- task_detach();
-
- // We send a message to this message queue when the ipmi state changes.
- // Don't free these messages - these messages are sent async so the
- // consumer will free the message.
- msg_t* msg = NULL;
-
- uint8_t ctrl = 0;
-
- while(1)
- {
- mutex_lock(&iv_mutex);
-
- errlHndl_t err = readLPC(REG_CONTROL, ctrl);
-
- // Not sure there's much we can do here but commit the log
- // and let this thread fail.
- if (err)
- {
- mutex_unlock(&iv_mutex);
- IPMI_TRAC(ERR_MRK "polling loop encountered an error, exiting");
- errlCommit(err, IPMI_COMP_ID);
- break;
- }
- else
- {
- // If we're idle, tell the resoure provider to check for any
- // pending messages which were delayed due to contention. But don't
- // send a message every time we see idle, only if there we suspect
- // we sent EAGAINs.
- if ((ctrl & IDLE_STATE) == 0)
- {
- if (iv_eagains)
- {
- msg = msg_allocate();
- msg->type = IPMI::MSG_STATE_IDLE;
- msg_send(iv_eventQ, msg);
- iv_eagains = false;
- }
- }
- // If we see the B2H_ATN, there's a response waiting
- else if (ctrl & CTRL_B2H_ATN)
- {
- msg = msg_allocate();
- msg->type = IPMI::MSG_STATE_RESP;
- msg_send(iv_eventQ, msg);
- }
-
- // If we see the SMS_ATN, there's an event waiting
- else if (ctrl & CTRL_SMS_ATN)
- {
- IPMI_TRAC(INFO_MRK "sending state sms/event");
- msg = msg_allocate();
- msg->type = IPMI::MSG_STATE_EVNT;
- msg_send(iv_eventQ, msg);
-
- // Clear the SMS bit.
- errlHndl_t err = writeLPC(REG_CONTROL, CTRL_SMS_ATN);
-
- // Commit this error. There's no one to tell ...
- if (err)
- {
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
- }
- }
- }
- mutex_unlock(&iv_mutex);
-
- nanosleep(0, WAIT_TIME);
- }
- IPMI_TRAC(EXIT_MRK "poll_control_register" );
-}
-
-/**
- * @brief Performs a reset of the BT hardware
- */
-inline errlHndl_t IpmiDD::reset(void)
-{
- IPMI_TRAC("resetting the IPMI BT interface");
- return writeLPC(REG_INTMASK, INT_BMC_HWRST);
-}
-
-/**
- * @brief Performs an IPMI Message Write Operation
- */
-errlHndl_t IpmiDD::send(IPMI::BTMessage* i_msg)
-{
- errlHndl_t err = NULL;
- uint8_t ctrl = 0;
-
- mutex_lock(&iv_mutex);
- do
- {
- err = readLPC(REG_CONTROL, ctrl);
- if (err) { break; }
-
- // If the interface isn't idle, tell the caller to come back
- if ((ctrl & IDLE_STATE) != 0)
- {
- i_msg->iv_state = EAGAIN;
- iv_eagains = true;
- continue;
- }
-
- // Tell the interface we're writing. Per p. 135 of the
- // spec we *do not* set H_BUSY.
- err = writeLPC(REG_CONTROL, CTRL_CLR_WR_PTR);
- if (err) { break; }
-
- // Add the header size on as req_len is only the length of the data
- err = writeLPC(REG_HOSTBMC, i_msg->iv_len + IPMI_BT_HEADER_SIZE);
- if (err) { break; }
-
- err = writeLPC(REG_HOSTBMC, i_msg->iv_netfun);
- if (err) { break; }
-
- err = writeLPC(REG_HOSTBMC, i_msg->iv_seq);
- if (err) { break; }
-
- err = writeLPC(REG_HOSTBMC, i_msg->iv_cmd);
- if (err) { break; }
-
- for( size_t i = 0; (i < i_msg->iv_len) && (err == NULL); ++i)
- {
- err = writeLPC(REG_HOSTBMC, i_msg->iv_data[i]);
- }
- if (err) { break; }
-
- // If all is well, alert the host we sent bits.
- err = writeLPC(REG_CONTROL, CTRL_H2B_ATN);
- if (err) {break;}
-
- } while(false);
-
- mutex_unlock(&iv_mutex);
-
- // If we have an error, try to reset the interface.
- if (err)
- {
- reset();
- }
-
- // Don't bother reporting a write if we returned EAGAIN, the
- // upper layers will report the re-queue or whatever.
- if (i_msg->iv_state != EAGAIN)
- {
- IPMI_TRAC(INFO_MRK "write %s %x:%x seq %x len %x",
- err ? "err" : "ok",
- i_msg->iv_netfun, i_msg->iv_cmd, i_msg->iv_seq,
- i_msg->iv_len);
- }
-
- return err;
-}
-
-/**
- * @brief Read a response to an issued command, or an sms
- */
-errlHndl_t IpmiDD::receive(IPMI::BTMessage* o_msg)
-{
- errlHndl_t err = NULL;
- uint8_t ctrl = 0;
- bool marked_busy = false;
-
- mutex_lock(&iv_mutex);
-
- do
- {
- err = readLPC(REG_CONTROL, ctrl);
- if (err) { break; }
-
- // Tell the interface we're busy.
- err = writeLPC(REG_CONTROL, CTRL_H_BUSY);
- if (err) {break;}
-
- marked_busy = true;
-
- // Clear the pending state from the control register.
- // Note the spec distinctly says "after setting H_BUSY,
- // the host should clear this bit" - not at the same time.
- // This is the hand-shake; H_BUSY gates the BMC which allows
- // us to clear the ATN bits. Don't get fancy.
- err = writeLPC(REG_CONTROL, CTRL_B2H_ATN);
- if (err) {break;}
-
- // Tell the interface we're reading
- err = writeLPC(REG_CONTROL, CTRL_CLR_RD_PTR);
- if (err) {break;}
-
- // The first byte is the length, grab it so we can allocate a buffer.
- err = readLPC(REG_HOSTBMC, o_msg->iv_len);
- if (err) { break; }
-
- o_msg->iv_len -= IPMI_BT_HEADER_SIZE + 1;
-
- err = readLPC(REG_HOSTBMC, o_msg->iv_netfun);
- if (err) { break; }
-
- err = readLPC(REG_HOSTBMC, o_msg->iv_seq);
- if (err) { break; }
-
- err = readLPC(REG_HOSTBMC, o_msg->iv_cmd);
- if (err) { break; }
-
- err = readLPC(REG_HOSTBMC, o_msg->iv_cc);
- if (err) { break; }
-
- o_msg->iv_data = new uint8_t[o_msg->iv_len];
-
- for( size_t i = 0; (i < o_msg->iv_len) && (err == NULL); ++i)
- {
- err = readLPC(REG_HOSTBMC, o_msg->iv_data[i]);
- }
- if (err) { break; }
-
- } while(0);
-
- if (marked_busy)
- {
- // Clear the busy state (write 1 to toggle). Note if we get
- // an error from the writeLPC, we toss it and return the first
- // error as it likely has better information in it.
- delete writeLPC(REG_CONTROL, CTRL_H_BUSY);
- }
-
- mutex_unlock(&iv_mutex);
-
- IPMI_TRAC(INFO_MRK "read b2h %s %x:%x seq %x len %x cc %x",
- err ? "err" : "ok",
- o_msg->iv_netfun, o_msg->iv_cmd, o_msg->iv_seq,
- o_msg->iv_len, o_msg->iv_cc);
-
- return err;
-}
-
-/**
- * @brief Constructor
- */
-IpmiDD::IpmiDD(void):
- iv_eagains(false),
- iv_eventQ(msg_q_create())
-{
- mutex_init(&iv_mutex);
-
- // Start task to poll the control register
- // This is a singleton so this will only be called once, right?
- task_create( poll_control_register, NULL );
-
- return;
-}
diff --git a/src/usr/ipmi/ipmidd.H b/src/usr/ipmi/ipmidd.H
deleted file mode 100644
index a9b8ada8c..000000000
--- a/src/usr/ipmi/ipmidd.H
+++ /dev/null
@@ -1,174 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmidd.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-#ifndef __IPMI_IPMIDD_H
-#define __IPMI_IMPIDD_H
-
-#include <sys/msg.h>
-#include <ipmi/ipmiif.H>
-#include "ipmibt.H"
-
-/** @file ipmidd.H
- * @brief Provides the interfaces to the IPMI Device Driver
- */
-
-enum {
- // Registers. These are fixed for LPC/BT so we can hard-wire them
- REG_CONTROL = 0xE4,
- REG_HOSTBMC = 0xE5,
- REG_INTMASK = 0xE6,
-
- // Control register bits. The control register is interesting in that
- // writing 0's never does anything; all registers are either set to 1
- // when written with a 1 or toggled (1/0) when written with a one. So,
- // we don't ever need to read-modify-write, we can just write an or'd
- // mask of bits.
- CTRL_B_BUSY = (1 << 7),
- CTRL_H_BUSY = (1 << 6),
- CTRL_OEM0 = (1 << 5),
- CTRL_SMS_ATN = (1 << 4),
- CTRL_B2H_ATN = (1 << 3),
- CTRL_H2B_ATN = (1 << 2),
- CTRL_CLR_RD_PTR = (1 << 1),
- CTRL_CLR_WR_PTR = (1 << 0),
-
- IDLE_STATE = (CTRL_B_BUSY | CTRL_B2H_ATN |
- CTRL_SMS_ATN | CTRL_H2B_ATN),
-
- // Bit in the INMASK register which signals to the BMC
- // to reset it's end of things.
- INT_BMC_HWRST = (1 << 7),
-
- // How long to sychronously wait for the device to change state (in ns)
- WAIT_TIME = 100000000,
-};
-
-/**
- * @brief IPMI Device Driver Class
- * Provides read/write message capabilities.
- */
-class IpmiDD
-{
- public:
- /**
- * @brief Poll the control register
- *
- * @parm void
- */
- void pollCtrl(void);
-
- /**
- * @brief Performs an IPMI message read operation
- *
- * @param[out] o_msg - Destination buffer for data
- *
- * @return errlHndl_t NULL on success
- */
-
- errlHndl_t receive(IPMI::BTMessage* o_msg);
-
- /**
- * @brief Performs an IPMI message write operation
- *
- * @param[in] i_msg - Location of data to be written
- *
- * @return errlHndl_t NULL on success
- */
- errlHndl_t send(IPMI::BTMessage* i_msg);
-
- /**
- * @brief Performs a reset of the BT hardware
- *
- * @param void
- *
- * @return errlHndl_t NULL on success
- */
- errlHndl_t reset(void);
-
- /**
- * @brief Get the queue on which IpmiDD publishes hardware events
- *
- * The events on the queue are consumed by IpmiRP. This "publish" approach
- * avoids circular dependencies between the two components.
- */
- msg_q_t eventQueue(void)
- { return iv_eventQ; }
-
- /**
- * @brief Constructor
- *
- * @parm void
- */
- IpmiDD(void);
-
- private:
- /**
- * @brief Read an address from LPC space
- *
- * @parm i_addr Absolute LPC Address
- * @parm o_data Buffer to read data into
- *
- * @return Error from operation
- */
- errlHndl_t readLPC(const uint32_t i_addr, uint8_t& o_data);
-
- /**
- * @brief Write an address from LPC space
- *
- * @parm i_addr Absolute LPC Address
- * @parm i_data Data to write
- *
- * @return Error from operation
- */
- errlHndl_t writeLPC(const uint32_t i_addr, uint8_t i_data);
-
- private: // Variables
-
- /**
- * @brief Mutex used to protect internal state
- */
- mutex_t iv_mutex;
-
- /**
- * @brief True if we told the RP to try a write again
- */
- bool iv_eagains;
-
- /**
- * @brief Publishes changes to device state
- *
- * To clarify, IpmiDD does not consume any messages from this queue. The
- * queue exists purely for the purpose of another component to consume IPMI
- * hardware events (currently, IpmiRP). IpmiDD performs an asynchronous
- * msg_send() to deliver the events to the listening task.
- */
- msg_q_t iv_eventQ;
-
- // Disallow copying this class.
- IpmiDD& operator=(const IpmiDD&);
- IpmiDD(const IpmiDD&);
-};
-
-
-#endif
diff --git a/src/usr/ipmi/ipmifru.C b/src/usr/ipmi/ipmifru.C
deleted file mode 100644
index 66bb8d9ae..000000000
--- a/src/usr/ipmi/ipmifru.C
+++ /dev/null
@@ -1,356 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmifru.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file ipmifru.C
- * @brief IPMI fru inventory definition
- */
-
-#include "ipmifru.H"
-#include <devicefw/driverif.H>
-#include <devicefw/userif.H>
-
-#include <sys/task.h>
-#include <builtins.h>
-#include <initservice/taskargs.H>
-#include <initservice/initserviceif.H>
-
-#include <errl/errlmanager.H>
-#include <errl/errlentry.H>
-
-// Defined in ipmidd.C
-extern trace_desc_t * g_trac_ipmi;
-#define IPMI_TRAC(printf_string,args...) \
- TRACFCOMP(g_trac_ipmi,"fru: " printf_string,##args)
-
-#ifdef CONFIG_BMC_IPMI
-
-const uint8_t writeDataHeader = 3;
-const uint8_t readDataCmd = 4;
-
-/**
- * setup _start and handle barrier
- */
-
-/**
- * @brief Constructor
- */
-IpmiFRU::IpmiFRU(void):
- iv_msgQ(msg_q_create())
-{
- task_create(&IpmiFRU::start, NULL);
-}
-
-/**
- * @brief Destructor
- */
-IpmiFRU::~IpmiFRU(void)
-{
- msg_q_destroy(iv_msgQ);
-}
-
-void* IpmiFRU::start(void* unused)
-{
- Singleton<IpmiFRU>::instance().execute();
- return NULL;
-}
-
-/**
- * @brief Entry point of the fru ipmi thread
- */
-void IpmiFRU::execute(void)
-{
- // Mark as an independent daemon so if it crashes we terminate.
- task_detach();
-
- IPMI_TRAC(ENTER_MRK "execute: fru message loop");
- do {
- while (true)
- {
- msg_t* msg = msg_wait(iv_msgQ);
-
- const IPMIFRU::msg_type msg_type =
- static_cast<IPMIFRU::msg_type>(msg->type);
-
- // Invert the "default" by checking here. This allows the compiler
- // to warn us if the enum has an unhandled case but still catch
- // runtime errors where msg_type is set out of bounds.
- assert(msg_type <= IPMIFRU::MSG_LAST_TYPE,
- "msg_type %d not handled", msg_type);
-
- switch(msg_type)
- {
- case IPMIFRU::MSG_WRITE_FRU_DATA:
- sendWriteFruData(msg);
-
- // done with the msg
- msg_free(msg);
- break;
-
- case IPMIFRU::MSG_READ_FRU_DATA:
- sendReadFruData(msg);
- msg_respond(iv_msgQ, msg);
- break;
- };
- } // while
- } while (false);
-
- return;
-} // execute
-
-///
-/// @brief Send write_fru_data msg to IpmiRP
-/// called for msg->type MSG_WRITE_FRU_DATA
-///
-void IpmiFRU::sendWriteFruData(msg_t *i_msg)
-{
- errlHndl_t err = NULL;
- const size_t l_maxBuffer = IPMI::max_buffer();
-
- // pull out the data - deviceId and offset are in data[0]
- const uint8_t &l_deviceId = (i_msg->data[0] >> 32);
- uint16_t l_offset = (i_msg->data[0] & 0xFFFFFFFF);
- uint16_t l_dataOffset = 0; // start at the l_data[0]
-
- size_t l_dataSize = i_msg->data[1]; // FRU data size
- uint8_t *l_data = static_cast<uint8_t*>(i_msg->extra_data);
-
- IPMI_TRAC(ENTER_MRK "sendWriteFruData for dev 0x%x, size %d",
- l_deviceId, l_dataSize);
-
- while ((l_dataSize > 0) && (err == NULL))
- {
- size_t this_size = std::min(l_maxBuffer, l_dataSize + writeDataHeader);
- uint8_t *this_data = new uint8_t[this_size];
- const uint16_t l_fruSize = this_size - writeDataHeader;
-
- // copy device ID, offset, fru data to new buffer
- this_data[0] = l_deviceId;
- this_data[1] = l_offset & 0xFF;
- this_data[2] = l_offset >> 8;
- memcpy(&this_data[writeDataHeader], l_data + l_dataOffset, l_fruSize);
-
- IPMI_TRAC(INFO_MRK "sending write_fru_data fru size %d offset %d",
- l_fruSize, l_offset);
-
- // update the offsets for the next time around
- l_offset += l_fruSize;
- l_dataOffset += l_fruSize;
-
- IPMI::completion_code cc = IPMI::CC_UNKBAD;
- err = IPMI::sendrecv(IPMI::write_fru_data(), cc, this_size, this_data);
- if (err)
- {
- IPMI_TRAC(ERR_MRK "Failed to send write_fru_data dev 0x%x",
- l_deviceId);
- // err is set, so we'll break out of the while loop
- }
- else if (cc != IPMI::CC_OK)
- {
- IPMI_TRAC(ERR_MRK "Failed to send write_fru_data dev 0x%x CC 0x%x",
- l_deviceId, cc);
- // stop sending; breaks out of the while loop
- l_dataSize = 0;
- }
- else
- {
- l_dataSize -= l_fruSize;
- }
-
- // delete the buffer returned from sendrecv
- delete [] this_data;
-
- } // while there is data to send and no error
-
- if (err)
- {
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
- }
-
- // delete the space the caller allocated; we need to do this because
- // we're async relative to the caller
- delete [] l_data;
-
- return;
-} // sendWriteFruData
-
-void IpmiFRU::sendReadFruData(msg_t *i_msg)
-{
- errlHndl_t err = NULL;
-
- const uint8_t &l_deviceId = (i_msg->data[0] >> 32);
- uint16_t l_offset = (i_msg->data[0] & 0xFFFFFFFF);
- size_t l_dataSize = i_msg->data[1]; // FRU data size
- uint8_t *l_data = static_cast<uint8_t*>(i_msg->extra_data);
-
- uint16_t l_dataOffset = 0; // start at the l_data[0]
- size_t l_fruSize = 0;
-
- //TODO RTC 167956
- const size_t l_maxBuffer = 16;
-
- IPMI_TRAC(ENTER_MRK "sendReadFruData for dev 0x%x, size %d",
- l_deviceId, l_dataSize);
-
- while ((l_dataSize > 0) && (err == NULL))
- {
- size_t this_size = readDataCmd;
- uint8_t *this_data = new uint8_t[this_size];
-
- l_fruSize = std::min(l_dataSize, l_maxBuffer); // read data size
-
- // copy device ID, offset, fru data to new buffer
- this_data[0] = l_deviceId;
- this_data[1] = l_offset & 0xFF;
- this_data[2] = l_offset >> 8;
- this_data[3] = l_fruSize;
-
- IPMI_TRAC(INFO_MRK "sending read_fru_data fru size %d offset %d, "
- "data offset %d",
- l_fruSize, l_offset, l_dataOffset);
-
- IPMI::completion_code cc = IPMI::CC_UNKBAD;
- err = IPMI::sendrecv(IPMI::read_fru_data(), cc, this_size, this_data);
- if (err)
- {
- IPMI_TRAC(ERR_MRK "Failed to send read_fru_data dev 0x%x",
- l_deviceId);
- // err is set, so we'll break out of the while loop
- }
- else if (cc != IPMI::CC_OK)
- {
- IPMI_TRAC(ERR_MRK "Failed to send read_fru_data dev 0x%x CC 0x%x",
- l_deviceId, cc);
- // stop sending; breaks out of the while loop
- l_dataSize = 0;
- } else {
- this_size = this_data[0];
- this_size = std::min(this_size, l_dataSize);
- memcpy(l_data + l_dataOffset, &this_data[1], this_size);
- // update the offsets for the next time around
- l_offset += l_fruSize;
- l_dataOffset += l_fruSize;
- l_dataSize -= l_fruSize;
- }
-
- // delete the buffer returned from sendrecv
- delete [] this_data;
- }
-
- if (err)
- {
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
- }
-
- return;
-} // sendReadFruData
-
-namespace IPMIFRU
-{
- ///
- /// @brief Function to send fru data to the IpmiFRU msg queue
- ///
- void writeData(uint8_t i_deviceId, uint8_t *i_data,
- uint32_t i_dataSize, uint32_t i_offset)
- {
- IPMI_TRAC(ENTER_MRK "writeData(deviceId 0x%x size %d offset %d)",
- i_deviceId, i_dataSize, i_offset);
-
- // one message queue to the FRU thread
- static msg_q_t mq = Singleton<IpmiFRU>::instance().msgQueue();
-
- // send data in msg to fru thread
- msg_t *msg = msg_allocate();
-
- msg->type = MSG_WRITE_FRU_DATA;
- msg->data[0] = (static_cast<uint64_t>(i_deviceId) << 32) | i_offset;
- msg->data[1] = i_dataSize;
-
- uint8_t* l_data = new uint8_t[i_dataSize];
- memcpy(l_data, i_data, i_dataSize);
- msg->extra_data = l_data;
-
- //Send the msg (async) to the fru thread
- int rc = msg_send(mq, msg);
-
- //Return code is non-zero when the message queue is invalid
- //or the message type is invalid.
- if ( rc )
- {
- IPMI_TRAC(ERR_MRK "Failed (rc=%d) to send message for dev 0x%x.",
- rc, i_deviceId);
- delete [] l_data; // delete, since msg wasn't sent
- }
-
- IPMI_TRAC(EXIT_MRK "writeData");
- return;
- } // writeData
-
- void readData(uint8_t i_deviceId, uint8_t *io_data)
- {
- IPMI_TRAC(ENTER_MRK "readData(deviceId 0x%x", i_deviceId);
-
- // one message queue to the FRU thread
- static msg_q_t mq = Singleton<IpmiFRU>::instance().msgQueue();
- uint32_t i_offset = 0;
- size_t i_dataSize = IPMIFRU::MAX_RECORD_SIZE;
-
- // send data in msg to fru thread
- msg_t *msg = msg_allocate();
-
- msg->type = MSG_READ_FRU_DATA;
- msg->data[0] = (static_cast<uint64_t>(i_deviceId) << 32) | i_offset;
- msg->data[1] = i_dataSize;
-
- //Setup data structure to pass in message to read FRU record
- uint8_t *l_data = new uint8_t[i_dataSize];
- memset(l_data, 0, i_dataSize);
- memset(io_data, 0, i_dataSize);
- msg->extra_data = l_data;
-
- //Send the msg (sync) to the fru thread
- int rc = msg_sendrecv(mq, msg);
-
- //Return code is non-zero when the message queue is invalid
- //or the message type is invalid.
- if ( rc )
- {
- IPMI_TRAC(ERR_MRK "Failed (rc=%d) to send message to read"
- "FRU Inventory Record: %d",
- rc, i_deviceId);
- delete [] l_data; // delete, since msg wasn't sent
- return;
- }
-
- //Copy data from local data structure to output data structure
- memcpy(&io_data[0], l_data, i_dataSize);
- msg_free(msg);
-
- return;
- }
-
-}; // IPMIFRU namespace
-#endif // CONFIG_BMC_IPMI
diff --git a/src/usr/ipmi/ipmifru.H b/src/usr/ipmi/ipmifru.H
deleted file mode 100644
index a8cb4916b..000000000
--- a/src/usr/ipmi/ipmifru.H
+++ /dev/null
@@ -1,127 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmifru.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-#ifndef __IPMI_IPMIFRU_H
-#define __IPMI_IMPIFRU_H
-
-/**
- * @file ipmifru.H
- * @brief IPMI FRU inventory declariation
- */
-
-#include <stdint.h>
-#include <ipmi/ipmiif.H>
-#include <console/consoleif.H>
-
-
-/**
- *
- *
- */
-namespace IPMIFRU
-{
- void writeData(uint8_t i_deviceId, uint8_t *i_data,
- uint32_t i_dataSize, uint32_t i_offset = 0);
-
- /*
- * @brief Read the IPMI FRU Record
- * @param[in] deviceId - The device ID to be read
- * @param[in/out] data - The buffer pointing to the data read
- */
- void readData(uint8_t i_deviceId, uint8_t *io_data);
-
- enum msg_type
- {
- MSG_WRITE_FRU_DATA, // async message - no reply
- MSG_READ_FRU_DATA, // sync message - has reply
- // Used to check range. Leave as last.
- MSG_LAST_TYPE = MSG_READ_FRU_DATA,
- };
- enum record_info
- {
- MAX_RECORD_SIZE = 256,
- };
-}
-
-
-class IpmiFRU
-{
- public:
-
- /**
- * Thread start routine for the resource provider
- * @param[in] void*, unused
- */
- static void* start(void* unused);
-
- /**
- * Default constructor
- */
- IpmiFRU(void);
-
- /**
- * Destructor
- */
- ~IpmiFRU(void);
-
- /**
- * @brief Get the message queue associated with this FRU
- * @param[in] void
- * @return, a msg_q_t which is the message queue
- */
- inline msg_q_t msgQueue(void) const
- { return iv_msgQ; }
-
- private:
-
- /**
- * Entry point for the fru ipmi thread
- */
- void execute(void);
-
- /**
- * @brief Handle a message with fru inventory data; msg is async
- * @param[in] i_msg
- */
- void sendWriteFruData(msg_t *i_msg);
-
- /**
- * @brief Handle a message with fru inventory data; msg is sync
- * #param[in] i_msg
- */
- void sendReadFruData(msg_t *i_msg);
-
-
- /**
- * ipmi fru msg queue
- */
- msg_q_t iv_msgQ;
-
- // Disallow copying this class.
- IpmiFRU& operator=(const IpmiFRU&);
- IpmiFRU(const IpmiFRU&);
-};
-
-#endif
diff --git a/src/usr/ipmi/ipmifruinv.C b/src/usr/ipmi/ipmifruinv.C
deleted file mode 100644
index 175507d45..000000000
--- a/src/usr/ipmi/ipmifruinv.C
+++ /dev/null
@@ -1,2300 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmifruinv.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
-/* [+] International Business Machines Corp. */
-/* [+] Jim Yuan */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-#include <vector>
-#include <map>
-#include <vpd/mvpdenums.H>
-#include <devicefw/userif.H>
-#include <vpd/spdenums.H>
-#include <vpd/cvpdenums.H>
-#include <vpd/pvpdenums.H>
-#include <targeting/common/commontargeting.H>
-#include <targeting/common/utilFilter.H>
-#include <errl/errlmanager.H>
-#include <ipmi/ipmifruinv.H>
-#include <ipmi/ipmisensor.H>
-#include "ipmifru.H"
-#include "ipmifruinvprvt.H"
-#include <stdio.h>
-#include <assert.h>
-#include <pnor/pnorif.H>
-#include <ipmi/ipmi_reasoncodes.H>
-#include <console/consoleif.H>
-extern trace_desc_t * g_trac_ipmi;
-
-// JEDEC constants used to calculate memory module capacity
-#define JEDEC_DENSITY_MASK 7
-#define JEDEC_DENSITY_MIN_VALUE 256
-#define JEDEC_MEMORY_BUS_WIDTH_PRI_MASK 3
-#define JEDEC_MEMORY_BUS_WIDTH_PRI_MIN_VALUE 8
-#define JEDEC_DRAM_WIDTH_MASK 3
-#define JEDEC_DRAM_WIDTH_MIN_VALUE 4
-#define JEDEC_RANKS_MASK 3
-#define JEDEC_RANKS_MIN_VALUE 1
-
-/**
- * @brief Structure described mapping between JEDEC identifiers
- * and their decoded values.
- */
-struct JedecNameMap
-{
- uint16_t id;
- const char* decoded;
-};
-
-static const JedecNameMap jedecManufacturer[] =
-{
- { 0x014F, "Transcend Information" },
- { 0x017A, "Apacer Technology" },
- { 0x0198, "Kingston" },
- { 0x0230, "Corsair" },
- { 0x0245, "Siemens AG" },
- { 0x04F1, "Toshiba Corporation" },
- { 0x0831, "Baikal Electronics" },
- { 0x8001, "AMD" },
- { 0x8004, "Fujitsu" },
- { 0x802C, "Micron Technology" },
- { 0x8054, "Hewlett-Packard" },
- { 0x8089, "Intel" },
- { 0x8089, "Intel" },
- { 0x8096, "LG Semi" },
- { 0x80A4, "IBM" },
- { 0x80AD, "SK Hynix" },
- { 0x80CE, "Samsung Electronics" },
- { 0x859B, "Crucial Technology" },
- { 0x8983, "Hewlett Packard Enterprise" }
-};
-
-static const JedecNameMap jedecBasicType[] =
-{
- { 0x0B, "DDR3" },
- { 0x0C, "DDR4" },
- { 0x0E, "DDR4E" },
- { 0x0F, "LPDDR3" },
- { 0x10, "LPDDR4" }
-};
-
-static const JedecNameMap jedecModuleType[] =
-{
- { 0x01, "RDIMM" },
- { 0x02, "UDIMM" },
- { 0x03, "SODIMM" },
- { 0x04, "LRDIMM" },
- { 0x05, "MINI RDIMM" },
- { 0x06, "MINI UDIMM" },
- { 0x08, "SORDIMM 72b"},
- { 0x09, "SOUDIMM 72b" },
- { 0x0C, "SODIMM 16b" },
- { 0x0D, "SODIMM 32b" }
-};
-
-static const JedecNameMap jedecBusWidthPri[] =
-{
- { 0x00, "8-bit" },
- { 0x01, "16-bit" },
- { 0x02, "32-bit" },
- { 0x03, "64-bit" }
-};
-
-static const JedecNameMap jedecBusWidthExt[] =
-{
- { 0x00, "non-ECC" },
- { 0x01, "ECC" }
-};
-
-static const JedecNameMap jedecTckMin[] =
-{
- { 0x05, "3200" },
- { 0x06, "2666" },
- { 0x07, "2400" },
- { 0x08, "2133" },
- { 0x09, "1866" },
- { 0x0A, "1600" }
-};
-
-#define JEDEC_TABLE_SIZE(a) (sizeof(a) / sizeof(a[0]))
-
-/**
- * @brief Get decoded value of JEDEC id.
- * @param[in] i_spdId, SPD field identifier (type of JEDEC table)
- * @param[in] i_jedecId, JEDEC identifier
- * @return const char*, text string or NULL if identifier is unknown
- */
-static const char* jedecDecode(uint16_t i_spdId, uint16_t i_jedecId)
-{
- const JedecNameMap* l_table;
- size_t l_tableSize;
-
- switch (i_spdId)
- {
- case SPD::MODULE_MANUFACTURER_ID:
- l_table = jedecManufacturer;
- l_tableSize = JEDEC_TABLE_SIZE(jedecManufacturer);
- break;
- case SPD::BASIC_MEMORY_TYPE:
- l_table = jedecBasicType;
- l_tableSize = JEDEC_TABLE_SIZE(jedecBasicType);
- break;
- case SPD::MODULE_TYPE:
- l_table = jedecModuleType;
- l_tableSize = JEDEC_TABLE_SIZE(jedecModuleType);
- break;
- case SPD::MODULE_MEMORY_BUS_WIDTH_PRI:
- l_table = jedecBusWidthPri;
- l_tableSize = JEDEC_TABLE_SIZE(jedecBusWidthPri);
- break;
- case SPD::MODULE_MEMORY_BUS_WIDTH_EXT:
- l_table = jedecBusWidthExt;
- l_tableSize = JEDEC_TABLE_SIZE(jedecBusWidthExt);
- break;
- case SPD::TCK_MIN:
- l_table = jedecTckMin;
- l_tableSize = JEDEC_TABLE_SIZE(jedecTckMin);
- break;
- default:
- l_table = NULL;
- l_tableSize = 0;
- }
-
- for (size_t i = 0; i < l_tableSize; ++i)
- {
- if (l_table[i].id == i_jedecId)
- {
- return l_table[i].decoded;
- }
- }
-
- return NULL;
-}
-
-/**
- * @brief Compairs two pairs - used for std:sort
- * @param[in] lhs - left pair for comparison
- * @param[in] rhs - right pair for comparison
- */
-inline static bool comparePairs(
- const std::pair<TARGETING::TargetHandle_t, uint8_t>& i_lhs,
- const std::pair<TARGETING::TargetHandle_t, uint8_t>& i_rhs)
-{
- bool l_compare = i_lhs.second < i_rhs.second;
-
- // in case of a tie, if the left is a Node, sort it first.
- if (i_lhs.second == i_rhs.second)
- {
- if (TARGETING::TYPE_NODE==i_lhs.first->getAttr<TARGETING::ATTR_TYPE>())
- {
- l_compare = true;
- }
- }
- return l_compare;
-}
-
-IpmiFruInv::IpmiFruInv(TARGETING::TargetHandle_t i_target)
- :iv_target(i_target)
-{
-};
-
-IpmiFruInv::~IpmiFruInv()
-{}
-
-
-IpmiFruInv *IpmiFruInv::Factory(TARGETING::TargetHandleList i_targets,
- bool i_updateData)
-{
- IpmiFruInv *l_fru = NULL;
- TARGETING::TargetHandle_t l_target;
-
- assert( ! i_targets.empty(),
- "IpmiFruInv::Factory: Input was empty List of Targets");
- l_target = i_targets[0];
-
- switch (l_target->getAttr<TARGETING::ATTR_TYPE>())
- {
- case TARGETING::TYPE_DIMM:
- l_fru = new isdimmIpmiFruInv(l_target);
- break;
- case TARGETING::TYPE_PROC:
- l_fru = new procIpmiFruInv(l_target, i_updateData);
- break;
- case TARGETING::TYPE_MEMBUF:
- // A memory riser card will have a mem buff with a distinct FRU ID
- l_fru = new membufIpmiFruInv(l_target, i_targets, i_updateData);
- break;
- case TARGETING::TYPE_NODE:
- // When the planar eeprom is shared for planar vpd and memory vpd,
- // the node and membufs will have the same FRU ID. The node has
- // been sorted ahead of the membufs. The membufs are extra targets
- // for their ECIDs.
- l_fru = new backplaneIpmiFruInv(l_target, i_targets, i_updateData);
- break;
- case TARGETING::TYPE_SYS:
- // Use sys target for setting System Firmware Info
- l_fru = new systemFwIpmiFruInv(l_target);
- break;
- default:
- assert(false,
- "IpmiFruInv::Factory: No support for target type given: [%08x]",
- l_target->getAttr<TARGETING::ATTR_TYPE>());
- break;
- }
-
- return l_fru;
-}
-
-void IpmiFruInv::sendFruData(uint8_t i_deviceId)
-{
- if (iv_record_data.size() > 0)
- {
- //Use IMPIFRU::writeData to send data to service processor
- // it will do any error handling and memory management
- IPMIFRU::writeData(i_deviceId, &iv_record_data[0],
- iv_record_data.size(), IPMIFRUINV::DEFAULT_FRU_OFFSET);
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"IpmiFruInv::sendFruData: "
- "Not sending data for deviceId[%08x], no data found for this record.");
- }
-
- return;
-}
-
-
-void IpmiFruInv::printRecordDebugData(const std::vector<uint8_t> &i_data)
-{
- if (i_data.size() > 0)
- {
- TRACFBIN(g_trac_ipmi, "IpmiRecordData", &i_data[0], i_data.size());
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"IpmiRecordData empty");
- }
-}
-
-
-//This uses the template method design pattern
-// Since all IPMI Fru Inventory records all contain the same 5 sections
-// (whether they are populated or empty) this funciton will build all 5
-// sections, build the header for the entire record, and then combine all 5
-// records into one full record
-errlHndl_t IpmiFruInv::buildFruInvRecord(void)
-{
- errlHndl_t l_errl = NULL;
- std::vector<uint8_t> l_iu_data;
- std::vector<uint8_t> l_ci_data;
- std::vector<uint8_t> l_bi_data;
- std::vector<uint8_t> l_pi_data;
- std::vector<uint8_t> l_mr_data;
-
- do {
- //First build up all 5 records individually
- l_errl = buildInternalUseArea(l_iu_data);
- if (l_errl) { break; }
-
- l_errl = buildChassisInfoArea(l_ci_data);
- if (l_errl) { break; }
-
- l_errl = buildBoardInfoArea(l_bi_data);
- if (l_errl) { break; }
-
- l_errl = buildProductInfoArea(l_pi_data);
- if (l_errl) { break; }
-
- l_errl = buildMultiRecordInfoArea(l_mr_data);
- if (l_errl) { break; }
-
- //Now build common header with data for this FRU Inv Record
- buildCommonHeader(l_iu_data, l_ci_data, l_bi_data,
- l_pi_data, l_mr_data);
-
- //Combine everything into one full IPMI Fru Inventory Record
- completeRecord(l_iu_data, l_ci_data, l_bi_data,
- l_pi_data, l_mr_data);
-
- } while(0);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,"IpmiFruInv::buildFruInvRecord Error encountered"
- " building up Fru Inventory Record sections.");
- }
-
- return l_errl;
-}
-
-
-void IpmiFruInv::buildCommonHeader(
- const std::vector<uint8_t> &i_internal_use_data,
- const std::vector<uint8_t> &i_chassis_data,
- const std::vector<uint8_t> &i_board_data,
- const std::vector<uint8_t> &i_product_data,
- const std::vector<uint8_t> &i_multirecord_data)
-{
- //Use this variable to increment size of header as we go along to determine
- // offset for the subsequent area offsets
- uint32_t l_cur_data_offset = 0;
-
- //First byte is id for version of FRU Info Storage Spec used
- addHeaderFormat(iv_record_data);
-
- //2nd byte is offset to internal use data
- buildCommonHeaderSection(iv_record_data, i_internal_use_data.size(),
- l_cur_data_offset);
-
- //3rd byte is offset to chassis data
- buildCommonHeaderSection(iv_record_data, i_chassis_data.size(),
- l_cur_data_offset);
-
- //4th byte is offset to board data
- buildCommonHeaderSection(iv_record_data, i_board_data.size(),
- l_cur_data_offset);
-
- //5th byte is offset to product data
- buildCommonHeaderSection(iv_record_data, i_product_data.size(),
- l_cur_data_offset);
-
- //6th byte is offset to multirecord data
- buildCommonHeaderSection(iv_record_data, i_multirecord_data.size(),
- l_cur_data_offset);
-
- //7th byte is PAD
- padData(iv_record_data);
-
- //8th (Final byte of Header Format) is the checksum
- addDataChecksum(iv_record_data);
-}
-
-void IpmiFruInv::completeRecord(const std::vector<uint8_t> &i_internal_use_data,
- const std::vector<uint8_t> &i_chassis_data,
- const std::vector<uint8_t> &i_board_data,
- const std::vector<uint8_t> &i_product_data,
- const std::vector<uint8_t> &i_multirecord_data)
-{
- addDataToRecord(i_internal_use_data);
- addDataToRecord(i_chassis_data);
- addDataToRecord(i_board_data);
- addDataToRecord(i_product_data);
- addDataToRecord(i_multirecord_data);
-}
-
-//Helper function to simply combine vectors together
-void IpmiFruInv::addDataToRecord(const std::vector<uint8_t> &i_data)
-{
- iv_record_data.insert(iv_record_data.end(), i_data.begin(), i_data.end());
-}
-
-//Helper function to create an 'empty' record
-errlHndl_t IpmiFruInv::buildEmptyArea(std::vector<uint8_t> &i_data)
-{
- return NULL;
-}
-
-//Helper function to pad a data record. Most of the IPMI Fru Invenotry
-// Record format works with each section being a multiple of 8 bytes
-// so padding is needed to make records properly formatted
-void IpmiFruInv::padData(std::vector<uint8_t> &io_data)
-{
- uint8_t l_pad_remainder = (io_data.size() + IPMIFRUINV::CHECKSUM_SIZE) %
- IPMIFRUINV::RECORD_UNIT_OF_MEASUREMENT;
-
- if (l_pad_remainder)
- {
- io_data.insert(io_data.end(),
- IPMIFRUINV::RECORD_UNIT_OF_MEASUREMENT - l_pad_remainder,
- uint8_t(0));
- }
- return;
-}
-
-//Creates a 2's complement checksum at the end of the given data vector
-void IpmiFruInv::addDataChecksum(std::vector<uint8_t> &io_data)
-{
- uint8_t l_checksum_val = 0;
- std::vector<uint8_t>::iterator l_iter;
-
- for (l_iter = io_data.begin(); l_iter != io_data.end(); ++l_iter)
- {
- l_checksum_val += *l_iter;
- }
-
- // Push the Zero checksum as the last byte of this data
- // This appears to be a simple summation of all the bytes
- io_data.push_back(-l_checksum_val);
-
- return;
-}
-
-//The Common Header points to the offset for each of the 5 data record
-// sections, this function is used in helping to build that up.
-void IpmiFruInv::buildCommonHeaderSection(std::vector<uint8_t> &io_out_data,
- uint32_t i_section_data_size,
- uint32_t &io_cur_data_offset)
-{
- //Check if data for internal use section populated
- if (i_section_data_size == 0)
- {
- //Indicate record not prsent
- io_out_data.push_back(IPMIFRUINV::RECORD_NOT_PRESENT);
- }
- else {
- //Place data to define offset to internal_use_data section
- io_out_data.push_back((io_cur_data_offset +
- IPMIFRUINV::COMMON_HEADER_FORMAT_SIZE)
- / IPMIFRUINV::RECORD_UNIT_OF_MEASUREMENT);
- io_cur_data_offset += i_section_data_size;
- }
-
- return;
-}
-
-//Helper function to add the IPMI Fru Inventory Format to the
-// beginning of the data vector passed in
-void IpmiFruInv::addHeaderFormat(std::vector<uint8_t> &io_data)
-{
- //Add id for version of FRU Info Storage Spec used
- io_data.push_back(IPMIFRUINV::SPEC_VERSION);
- return;
-}
-
-//Helper function to complete the formatting for a given section
-// that can be completed prior to adding section data
-// It will add the spec version, create a placeholder for the data
-// size and set the language code if desired
-void IpmiFruInv::preFormatProcessing(std::vector<uint8_t> &io_data,
- bool i_setLanguageCode)
-{
- //Add id for version of FRU Info Storage Spec used
- addHeaderFormat(io_data);
-
- //Add Data Size - 0 as a placeholder, can edit after the data is finalized
- io_data.push_back(uint8_t(0));
-
- if (i_setLanguageCode)
- {
- //Add Language Code
- io_data.push_back(uint8_t(IPMIFRUINV::ENGLISH_LANGUAGE_CODE));
- }
-}
-//Helper function to complete the formatting for a given section
-// It will calculate overall section size,
-// pad the section if needed, and add the data checksum
-void IpmiFruInv::postFormatProcessing(std::vector<uint8_t> &io_data)
-{
- //This area needs to be padded to a multiple of 8 bytes (after checksum)
- padData(io_data);
-
- //Set size of data info area
- setAreaSize(io_data, 1);
-
- //Finally add board info checksum
- addDataChecksum(io_data);
-
- return;
-}
-
-//Helper function containing the logic to set the proper size of a data section
-void IpmiFruInv::setAreaSize(std::vector<uint8_t> &io_data, uint8_t i_offset)
-{
-
- io_data.at(i_offset) = (io_data.size() + IPMIFRUINV::CHECKSUM_SIZE)
- / IPMIFRUINV::RECORD_UNIT_OF_MEASUREMENT;
-
- return;
-}
-
-static inline uint8_t bcd2_to_int(uint8_t bcd)
-{
- return ((bcd >> 4) & 0xF) * 10 + (bcd & 0xF);
-}
-
-// Function to compute the correct data for the Mfg date/time section.
-// IPMI expects the time to be in seconds from 01/01/1996.
-errlHndl_t IpmiFruInv::formatMfgData(std::vector<uint8_t> i_mfgDateData,
- uint32_t& o_mfgDate)
-{
- errlHndl_t l_errl = NULL;
-
- // MB keyword size is 8 hex bytes, throw an error if it is smaller so we
- // don't do an invalid access.
- if (i_mfgDateData.size() != 8)
- {
- /*@
- * @errortype
- * @moduleid IPMI::MOD_IPMIFRU_INV
- * @reasoncode IPMI::RC_INVALID_VPD_DATA
- * @userdata1 Size of vpd data
- *
- * @devdesc VPD data is invalid size
- */
- l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
- IPMI::MOD_IPMIFRU_INV,
- IPMI::RC_INVALID_VPD_DATA,
- i_mfgDateData.size());
-
- TARGETING::Target* nodeTarget = NULL;
- TARGETING::PredicateCTM nodeFilter(TARGETING::CLASS_ENC,
- TARGETING::TYPE_NODE);
- TARGETING::TargetRangeFilter nodeItr(
- TARGETING::targetService().begin(),
- TARGETING::targetService().end(),
- &nodeFilter);
-
- nodeTarget = *nodeItr;
-
- // Callout out node since that is where the VPD lives
- l_errl->addHwCallout(nodeTarget,
- HWAS::SRCI_PRIORITY_HIGH,
- HWAS::NO_DECONFIG,
- HWAS::GARD_NULL );
-
- }
- else
- {
- // Convert Centuries / Years / months / day / hour / minute / second
- // into a uint64 representing number of minute since 1/1/96
-
- // The vpd data is expected to be in this format VVCCYYmmDDHHMMSS
- // Note that it is Binary Coded Decimal(BCD). Need to translate to int.
- uint8_t century = bcd2_to_int(i_mfgDateData.at(1));
- uint8_t year = bcd2_to_int(i_mfgDateData.at(2));
- uint8_t month = bcd2_to_int(i_mfgDateData.at(3));
- uint8_t day = bcd2_to_int(i_mfgDateData.at(4));
- uint8_t hour = bcd2_to_int(i_mfgDateData.at(5));
- uint8_t minute = bcd2_to_int(i_mfgDateData.at(6));
-
- // Subtract year
- uint8_t numOfYears = (century*100 + year) - 1996;
- // Subtract month
- uint8_t numOfMonths = month - 1;
- // Subtract day
- uint16_t numOfDays = day - 1;
-
- // Add the specific number of days for the months given
- for (uint8_t i=0; i < numOfMonths; i++)
- {
- numOfDays += daysInMonth[i];
- }
-
- // Add the number of days for the number of year given
- numOfDays += (numOfYears*365);
-
- // Add a day for every leap year
- // Check if we need to consider the current year
- if (month <= 2)
- {
- // We don't need to consider this year for a leap year, as it
- // wouldn't have happened yet. Decrement a year.
- year = year - 1;
- }
-
- uint8_t numLeapYears = 0;
- // For every year from 1996 until the build date year, check if it's a
- // leap year
- for(uint16_t i = 1996; i <= (century*100 + year); i++)
- {
- // If the year is divisible by 4, its a leap year. Don't have to
- // worry about centuries since the only possible century is 2000
- // and it was a leap year.
- if(i % 4 == 0)
- {
- numLeapYears++;
- }
- }
-
- numOfDays += numLeapYears;
-
- // Convert into minutes
- o_mfgDate = (((numOfDays*24)*60) + (hour*60) + minute);
-
- }
-
- return l_errl;
-}
-
-// Function to set the data for the Mfg date/time section.
-void IpmiFruInv::setMfgData(std::vector<uint8_t> &io_data,
- std::vector<uint8_t> &mfgDateData)
-{
- errlHndl_t l_errl = NULL;
- uint32_t mfgDate = 0;
-
- // Pass mfgDateData vector to format function to get the minute integer
- l_errl = formatMfgData(mfgDateData, mfgDate);
- if (l_errl)
- {
- // MFG date isn't entierly necessary. Let's just delete and
- // continue.
- TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::buildBoardInfoArea - "
- "Error from formatMfgData. Using default MFG Date/Time.");
- io_data.push_back(0);
- io_data.push_back(0);
- io_data.push_back(0);
- delete l_errl;
- l_errl = nullptr;
- }
- else
- {
- if(((mfgDate & 0xFF000000) >> 24) != 0)
- {
- // If there is data in these bits, we have exceeded the
- // maximum time we can display (IPMI only takes in 3 bytes
- // of hex, FFFFFF)
- TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::buildBoardInfoArea "
- "- Exeeded maximum allowed build date to display. Using "
- "default MFG Date/Time.");
- io_data.push_back(0);
- io_data.push_back(0);
- io_data.push_back(0);
- }
- else
- {
- // Convert mfgDate to hex
- uint8_t l_leastSig = (mfgDate & 0x000000FF);
- uint8_t l_middleSig = (mfgDate & 0x0000FF00) >> 8;
- uint8_t l_mostSig = (mfgDate & 0x00FF0000) >> 16;
-
- // Push data into io_data - least significant byte first
- io_data.push_back(l_leastSig);
- io_data.push_back(l_middleSig);
- io_data.push_back(l_mostSig);
- }
- }
-}
-
-
-//##############################################################################
-isdimmIpmiFruInv::isdimmIpmiFruInv( TARGETING::TargetHandle_t i_target )
- :IpmiFruInv(i_target)
-{
-
-};
-
-errlHndl_t isdimmIpmiFruInv::buildInternalUseArea(std::vector<uint8_t> &io_data)
-{
- //This section not needed for isdimm type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t isdimmIpmiFruInv::buildChassisInfoArea(std::vector<uint8_t> &io_data)
-{
- //This section not needed for isdimm type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t isdimmIpmiFruInv::buildBoardInfoArea(std::vector<uint8_t> &io_data)
-{
- //This section not needed for isdimm type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t isdimmIpmiFruInv::buildMultiRecordInfoArea(
- std::vector<uint8_t> &io_data)
-{
- //This section not needed for isdimm type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t isdimmIpmiFruInv::buildProductInfoArea(std::vector<uint8_t> &io_data)
-{
- errlHndl_t l_errl = NULL;
-
- do {
- //Set formatting data that goes at the beginning of the record
- preFormatProcessing(io_data, true);
-
- //Set Manufacturer Name - Use full info with decoded name
- l_errl = addSpdManufacturer(io_data);
- if (l_errl) { break; }
- //Set Product Name - Use detailed description
- l_errl = addSpdDetails(io_data);
- if (l_errl) { break; }
- //Set Product Part/Model Number
- l_errl = addVpdData(io_data, SPD::MODULE_PART_NUMBER, true);
- if (l_errl) { break; }
- //Set Product Version
- l_errl = addVpdData(io_data, SPD::MODULE_REVISION_CODE);
- if (l_errl) { break; }
- //Set Product Serial Number
- l_errl = addVpdData(io_data, SPD::MODULE_SERIAL_NUMBER);
- if (l_errl) { break; }
-
- //Add Asset Tag
- io_data.push_back(uint8_t(0)); //No Asset Tag needed - O bytes
-
- //FRU File ID - Empty
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
- io_data.push_back(uint8_t(0)); // Empty FRU File ID bytes
- io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
-
- } while (0);
-
- //Finalize section formatting
- postFormatProcessing(io_data);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,"isdimIpmiFruInv::buildProductInfoArea - Errors "
- "collecting product info data from VPD");
- }
-
- return l_errl;
-}
-
-errlHndl_t isdimmIpmiFruInv::addVpdData(std::vector<uint8_t> &io_data,
- uint8_t i_keyword,
- bool i_ascii)
-{
- size_t l_vpdSize = 0;
- errlHndl_t l_errl = NULL;
-
- do {
- //First get size with NULL call:
- l_errl = deviceRead(iv_target,
- NULL,
- l_vpdSize,
- DEVICE_SPD_ADDRESS(i_keyword));
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,"isdimmIpmiFruInv::addVpdData - "
- "Error while reading SPD keyword size for keyword 0x%x",
- i_keyword);
- break;
- }
-
- //Assert if vpd field is too large to fit in IPMI fru inventory format
- assert(l_vpdSize < IPMIFRUINV::TYPELENGTH_BYTE_ASCII);
-
- if (l_vpdSize > 0)
- {
- //Determine how big data is and expand it to handle the soon to
- //be read VPD data
- uint8_t l_offset = io_data.size();
- io_data.resize(l_offset + 1 + l_vpdSize);
-
- //Add on the data to the type/length byte indicating it is ascii
- // otherwise leave it as binary
- if (i_ascii)
- {
- io_data.at(l_offset) = l_vpdSize
- + IPMIFRUINV::TYPELENGTH_BYTE_ASCII;
- }
- else
- {
- io_data.at(l_offset) = l_vpdSize;
- }
- l_offset += 1;
-
- //Read the VPD data directly into fru inventory data buffer
- l_errl = deviceRead(iv_target,&io_data[l_offset], l_vpdSize,
- DEVICE_SPD_ADDRESS(i_keyword));
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"isdimmIpmiFruInv::addVpdData - "
- " No size returned for SPD keyword");
- }
-
- } while(0);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi, "addVpdData - Error acquiring data from Vpd.");
- }
-
- return l_errl;
-}
-
-errlHndl_t isdimmIpmiFruInv::addSpdManufacturer(std::vector<uint8_t> &io_data)
-{
- const uint16_t i_keyword = SPD::MODULE_MANUFACTURER_ID;
- uint16_t l_manufacturerId;
- size_t l_fieldSize = sizeof(l_manufacturerId);
-
- // Read manufacturer ID from SDP
- const errlHndl_t l_errl = deviceRead(iv_target,
- &l_manufacturerId,
- l_fieldSize,
- DEVICE_SPD_ADDRESS(i_keyword));
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,
- "isdimmIpmiFruInv::addSpdManufacturer - "
- "Error while reading SPD keyword 0x%04x",
- i_keyword);
- }
- else
- {
- // SPD values are stored in LE format
- l_manufacturerId = le16toh(l_manufacturerId);
-
- // Decode and put manufacturer name into the message buffer
- const char* l_name = jedecDecode(i_keyword, l_manufacturerId);
- if (l_name)
- {
- const size_t l_len = strlen(l_name);
- io_data.push_back(l_len + IPMIFRUINV::TYPELENGTH_BYTE_ASCII);
- io_data.insert(io_data.end(), l_name, l_name + l_len);
- }
- else {
- char l_buf[IPMIFRUINV::MAX_ASCII_FIELD_SIZE];
- const size_t l_len = snprintf(l_buf, sizeof(l_buf),
- "Unknown (0x%04x)", l_manufacturerId);
- io_data.push_back(l_len + IPMIFRUINV::TYPELENGTH_BYTE_ASCII);
- io_data.insert(io_data.end(), l_buf, l_buf + l_len);
- }
- }
-
- return l_errl;
-}
-
-errlHndl_t isdimmIpmiFruInv::addSpdDetails(std::vector<uint8_t> &io_data)
-{
- errlHndl_t l_errl = NULL;
-
- do {
- // All fields that we need are 1 byte
- size_t l_fieldSize = sizeof(uint8_t);
- const uint8_t l_invalidValue = 0xff;
-
- // Read detailed memory module info
-
- uint8_t l_basicType = l_invalidValue;
- l_errl = deviceRead(iv_target, &l_basicType, l_fieldSize,
- DEVICE_SPD_ADDRESS(SPD::BASIC_MEMORY_TYPE));
- if (l_errl) { break; }
-
- uint8_t l_moduleType = l_invalidValue;
- l_errl = deviceRead(iv_target, &l_moduleType, l_fieldSize,
- DEVICE_SPD_ADDRESS(SPD::MODULE_TYPE));
- if (l_errl) { break; }
-
- uint8_t l_busWidthPri = l_invalidValue;
- l_errl = deviceRead(iv_target, &l_busWidthPri, l_fieldSize,
- DEVICE_SPD_ADDRESS(SPD::MODULE_MEMORY_BUS_WIDTH_PRI));
- if (l_errl) { break; }
-
- uint8_t l_busWidthExt = l_invalidValue;
- l_errl = deviceRead(iv_target, &l_busWidthExt, l_fieldSize,
- DEVICE_SPD_ADDRESS(SPD::MODULE_MEMORY_BUS_WIDTH_EXT));
- if (l_errl) { break; }
-
- uint8_t l_tckMin = l_invalidValue;
- l_errl = deviceRead(iv_target, &l_tckMin, l_fieldSize,
- DEVICE_SPD_ADDRESS(SPD::TCK_MIN));
- if (l_errl) { break; }
-
- uint8_t l_density = l_invalidValue;
- l_errl = deviceRead(iv_target, &l_density, l_fieldSize,
- DEVICE_SPD_ADDRESS(SPD::DENSITY));
- if (l_errl) { break; }
-
- uint8_t l_dramWidth = l_invalidValue;
- l_errl = deviceRead(iv_target, &l_dramWidth, l_fieldSize,
- DEVICE_SPD_ADDRESS(SPD::MODULE_DRAM_WIDTH));
- if (l_errl) { break; }
-
- uint8_t l_ranks = l_invalidValue;
- l_errl = deviceRead(iv_target, &l_ranks, l_fieldSize,
- DEVICE_SPD_ADDRESS(SPD::MODULE_RANKS));
- if (l_errl) { break; }
-
- // Calculate capacity of memory module
- uint16_t l_capacityGiB = 0;
- if (l_density <= JEDEC_DENSITY_MASK &&
- l_busWidthPri <= JEDEC_MEMORY_BUS_WIDTH_PRI_MASK &&
- l_dramWidth <= JEDEC_DRAM_WIDTH_MASK &&
- l_ranks <= JEDEC_RANKS_MASK)
- {
- // Get density
- // JEDEC Standard No. 21-C. Page 4.1.2.12 – 9
- // density = 256 Mb* (2 ^ density) / 8 = 32 MB * (2 ^ density)
- const uint32_t l_realDensity = (JEDEC_DENSITY_MIN_VALUE / 8) << l_density;
-
- // Calculate the Primary Bus Width
- // JEDEC Standard No. 21-C. Page 4.1.2.12 – 15
- // b00 - 8 bits ... b11 - 64 bits. All others reserved.
- const uint32_t l_realBusWidth = JEDEC_MEMORY_BUS_WIDTH_PRI_MIN_VALUE << l_busWidthPri;
-
- // Calculate the SDRAM Device Width
- // JEDEC Standard No. 21-C. Page 4.1.2.12 – 14
- // b00 - 4 bits ... b11 - 32 bits. All others reserved.
- const uint32_t l_realDevWidth = JEDEC_DRAM_WIDTH_MIN_VALUE << l_dramWidth;
-
- // Calculate the Number of Package Ranks per DIMM
- // JEDEC Standard No. 21-C. Page 4.1.2.12 – 14
- // b00 - 1 package rank ... b11 - 4 package ranks. All others reserved.
- const uint32_t l_realRanks = JEDEC_RANKS_MIN_VALUE + l_ranks;
-
- // Calculate the Module Capacity (in GiB >> 10) according to the formula
- // from the JEDEC Standard specification No. 21-C. Page 4.1.2.12 – 15
- l_capacityGiB = (l_realDensity * (l_realBusWidth / l_realDevWidth) * l_realRanks) >> 10;
- }
-
- // Construct detailed string description
- char l_desc[IPMIFRUINV::MAX_ASCII_FIELD_SIZE] = { 0 };
- // Always store last null-termination symbol
- const size_t l_descSz = sizeof(l_desc) - 1;
-
- const char* l_decoded;
-
- l_decoded = jedecDecode(SPD::BASIC_MEMORY_TYPE, l_basicType);
- if (l_decoded)
- {
- strncpy(l_desc, l_decoded, l_descSz);
- }
- else
- {
- snprintf(l_desc, l_descSz, "N/A (%02x)", l_basicType);
- }
-
- l_decoded = jedecDecode(SPD::TCK_MIN, l_tckMin);
- if (l_decoded)
- {
- strncat(l_desc, "-", l_descSz);
- strncat(l_desc, l_decoded, l_descSz);
- }
-
- if (l_capacityGiB)
- {
- char l_buff[16] = { 0 };
- snprintf(l_buff, sizeof(l_buff) - 1, " %iGiB", l_capacityGiB);
- strncat(l_desc, l_buff, l_descSz);
- }
-
- l_decoded = jedecDecode(SPD::MODULE_MEMORY_BUS_WIDTH_PRI, l_busWidthPri);
- if (l_decoded)
- {
- strncat(l_desc, " ", l_descSz);
- strncat(l_desc, l_decoded, l_descSz);
- }
-
- l_decoded = jedecDecode(SPD::MODULE_MEMORY_BUS_WIDTH_EXT, l_busWidthExt);
- if (l_decoded)
- {
- strncat(l_desc, " ", l_descSz);
- strncat(l_desc, l_decoded, l_descSz);
- }
-
- l_decoded = jedecDecode(SPD::MODULE_TYPE, l_moduleType);
- if (l_decoded)
- {
- strncat(l_desc, " ", l_descSz);
- strncat(l_desc, l_decoded, l_descSz);
- }
-
- // Put detailed description into the message buffer
- const size_t l_len = strlen(l_desc);
- io_data.push_back(l_len + IPMIFRUINV::TYPELENGTH_BYTE_ASCII);
- io_data.insert(io_data.end(), l_desc, l_desc + l_len);
-
- } while(0);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,
- "isdimmIpmiFruInv::addSpdDetails - "
- "Error while reading SPD data");
- }
-
- return l_errl;
-}
-
-//##############################################################################
-procIpmiFruInv::procIpmiFruInv( TARGETING::TargetHandle_t i_target,
- bool i_isUpdate )
- :IpmiFruInv(i_target),
- iv_isUpdate(i_isUpdate)
-{
-};
-
-errlHndl_t procIpmiFruInv::buildInternalUseArea(std::vector<uint8_t> &io_data)
-{
- //This section not needed for proc type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t procIpmiFruInv::buildChassisInfoArea(std::vector<uint8_t> &io_data)
-{
- //This section not needed for proc type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t procIpmiFruInv::buildBoardInfoArea(std::vector<uint8_t> &io_data)
-{
- errlHndl_t l_errl = NULL;
-
- do {
- //Set formatting data that goes at the beginning of the record
- preFormatProcessing(io_data, true);
-
- //MFG Date/Time - Blank
- io_data.push_back(0);
- io_data.push_back(0);
- io_data.push_back(0);
-
- //Board Manufacturer - IBM
- //Board MFG - Type/Length Byte
- // - Indicate 8-bit Ascii + Latin 1 (0xC0)
- // - and a size of 3 for "IBM" - 0x3
- // - add together and the value for this byte is 0xC3
- io_data.push_back(0xC3);
- // - Now put in 'IBM'
- io_data.push_back('I');
- io_data.push_back('B');
- io_data.push_back('M');
-
- //Set Board Info description
- l_errl = addVpdData(io_data, MVPD::VINI, MVPD::DR, true);
- if (l_errl) { break; }
- //Set Board Info serial number
- l_errl = addVpdData(io_data, MVPD::VRML, MVPD::SN, true);
- if (l_errl) { break; }
- //Set Board part number
- l_errl = addVpdData(io_data, MVPD::VRML, MVPD::PN, true);
- if (l_errl) { break; }
- //Set Board FRU File ID
- l_errl = addVpdData(io_data, MVPD::VINI, MVPD::VZ);
- if (l_errl) { break; }
-
- //Push Fru File ID Byte - NULL
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
-
- //Get EC Data
- TARGETING::ATTR_EC_type ecInfo;
- bool getEC = iv_target->tryGetAttr<TARGETING::ATTR_EC>(ecInfo);
-
- //Get ECID Data
- TARGETING::ATTR_ECID_type ecidInfo;
- bool getEcid = iv_target->tryGetAttr<TARGETING::ATTR_ECID>(ecidInfo);
-
- //Only add ECID Data if in an update scenario
- if (getEcid && iv_isUpdate == true)
- {
- addEcidData(iv_target, ecidInfo, io_data);
- }
- //Add in the EC Data whether we're in an update scenario or not.
- //We have the EC info after discover_targets()
- if (getEC)
- {
- addECData(iv_target, ecInfo, io_data);
- }
-
- if(!getEC && !(getEcid && iv_isUpdate))
- {
- //Indicate no custom fields if ecid and ec data not found
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
- }
-
- if (iv_isUpdate == true)
- {
- std::vector<TARGETING::TargetHandle_t> l_procList;
- l_procList.push_back(iv_target);
- customData(l_procList, io_data);
- }
-
- //Indicate end of custom fields
- io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
-
- } while (0);
-
- //Complete formatting for this data record
- postFormatProcessing(io_data);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,"buildBoardInfoArea - Errors Collecting ISDimm "
- "FRU Inventory Board Info Data");
- }
-
- return l_errl;
-}
-
-errlHndl_t procIpmiFruInv::buildProductInfoArea(std::vector<uint8_t> &io_data)
-{
- //This section not needed for proc type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t procIpmiFruInv::buildMultiRecordInfoArea(
- std::vector<uint8_t> &io_data)
-{
- //This section not needed for proc type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t procIpmiFruInv::addVpdData(std::vector<uint8_t> &io_data,
- uint8_t i_record,
- uint8_t i_keyword,
- bool i_ascii,
- bool i_typeLengthByte)
-{
- errlHndl_t l_errl = NULL;
-
- l_errl = addCommonVpdData(iv_target,
- io_data,
- DeviceFW::MVPD,
- i_record,
- i_keyword,
- i_ascii,
- i_typeLengthByte);
- return l_errl;
-}
-
-
-//##############################################################################
-backplaneIpmiFruInv::backplaneIpmiFruInv( TARGETING::TargetHandle_t i_target,
- TARGETING::TargetHandleList i_extraTargets,
- bool i_isUpdate)
- :IpmiFruInv(i_target),
- iv_isUpdate(i_isUpdate),
- iv_extraTargets(i_extraTargets)
-{
-};
-
-errlHndl_t backplaneIpmiFruInv::buildInternalUseArea(
- std::vector<uint8_t> &io_data)
-{
- //This section not needed for the backplane type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t backplaneIpmiFruInv::buildChassisInfoArea(
- std::vector<uint8_t> &io_data)
-{
- errlHndl_t l_errl = NULL;
-
- do {
- //Set formatting data that goes at the beginning of the record
- preFormatProcessing(io_data, false);
- //Set Chassis Enclosure Type - Not Ascii
- // Also, do not include type/length byte
- l_errl = addVpdData(io_data, PVPD::OSYS, PVPD::ET, false, false);
-
- //Support Legacy VPD without OSYS record
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::buildChassisInfoArea - "
- " Using Legacy Chassis VPD Data");
- //Delete errorlog and use Default data and Legacy VPD Fields
- delete l_errl;
- l_errl = NULL;
-
- //Set default chassis type
- io_data.push_back(IPMIFRUINV::DEFAULT_CHASSIS_TYPE);
- //Set chassis part number - ascii formatted field
- l_errl = addVpdData(io_data, PVPD::OPFR, PVPD::VP, true);
- if (l_errl) { break; }
- //Set chassis serial number - ascii formatted field
- l_errl = addVpdData(io_data, PVPD::OPFR, PVPD::VS, true);
- if (l_errl) { break; }
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::buildChassisInfoArea - "
- " Using NEW OSYS RECORD FOR Chassis VPD Data");
-
- //Set chassis part number - ascii formatted field
- l_errl = addVpdData(io_data, PVPD::OSYS, PVPD::MM, true);
- if (l_errl) { break; }
-
- //Set chassis serial number - ascii formatted field
- l_errl = addVpdData(io_data, PVPD::OSYS, PVPD::SS, true);
- if (l_errl) { break; }
-
- }
-
- //Indicate no custom fields
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
- io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
-
- } while (0);
-
- //Complete record data formatting
- postFormatProcessing(io_data);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::buildChassisInfoArea - "
- "Errors collecting chassis info data");
- }
-
- return l_errl;
-}
-
-errlHndl_t backplaneIpmiFruInv::buildBoardInfoArea(
- std::vector<uint8_t> &io_data)
-{
- errlHndl_t l_errl = NULL;
-
- do {
- //Set formatting data that goes at the beginning of the record
- preFormatProcessing(io_data, true);
-
- // Set Mfg Build date
- // Grab VPD data into seperate data vector
- std::vector<uint8_t> mfgDateData;
- l_errl = addVpdData(mfgDateData, PVPD::OPFR, PVPD::MB, false, false);
- if (l_errl) { break; }
-
- // Pass that to the function that sets the Build date
- setMfgData(io_data, mfgDateData);
-
- //Set Vendor Name - ascii formatted data
- l_errl = addVpdData(io_data, PVPD::OPFR, PVPD::VN, true);
- if (l_errl) { break; }
-
- //Set Product Name - ascii formatted data
- l_errl = addVpdData(io_data, PVPD::OPFR, PVPD::DR, true);
- if (l_errl) { break; }
-
- //Set Product Serial number - ascii formatted data
- TARGETING::ATTR_SERIAL_NUMBER_type l_sn = {'0'};
- if( !( iv_target->
- tryGetAttr<TARGETING::ATTR_SERIAL_NUMBER>
- ( l_sn) ) )
- {
- // Should not fail. Need to use tryGetAttr due to complex type.
- // Use zeros if fails.
- TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::buildBoardInfoArea - "
- "Error getting serial number attribute");
- }
- // The attribute size is 18. The vpd is 16. Only use 16.
- addCommonAttrData(io_data,
- (uint8_t *)&l_sn,
- VPD_SN_PN_VPD_SIZE);
-
- //Set Product Part number - ascii formatted data
- TARGETING::ATTR_PART_NUMBER_type l_pn = {'0'};
- if( !( iv_target->
- tryGetAttr<TARGETING::ATTR_PART_NUMBER>
- ( l_pn) ) )
- {
- // Should not fail. Need to use tryGetAttr due to complex type.
- // Use zeros if fails.
- TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::buildBoardInfoArea - "
- "Error getting part number attribute");
- }
-
- // The attribute size is 18. The vpd is 16. Only use 16.
- addCommonAttrData(io_data,
- (uint8_t *)&l_pn,
- VPD_SN_PN_VPD_SIZE);
-
- //Push Fru File ID Byte - NULL
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
- //Indicate End of Custom Fields
- io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
-
-
- } while (0);
-
- //Complete record data formatting
- postFormatProcessing(io_data);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::buildBoardInfoArea - "
- "Errors collecting board info data");
- }
-
- return l_errl;
-}
-
-errlHndl_t backplaneIpmiFruInv::buildProductInfoArea(
- std::vector<uint8_t> &io_data)
-{
- //This section not needed for the backplane type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t backplaneIpmiFruInv::buildMultiRecordInfoArea(
- std::vector<uint8_t> &io_data)
-{
- //This section not needed for the backplane type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t backplaneIpmiFruInv::addVpdData(std::vector<uint8_t> &io_data,
- uint8_t i_record,
- uint8_t i_keyword,
- bool i_ascii,
- bool i_typeLengthByte)
-
-{
- errlHndl_t l_errl = NULL;
-
- l_errl = addCommonVpdData(iv_target,
- io_data,
- DeviceFW::PVPD,
- i_record,
- i_keyword,
- i_ascii,
- i_typeLengthByte);
-
- return l_errl;
-}
-
-//##############################################################################
-systemFwIpmiFruInv::systemFwIpmiFruInv( TARGETING::TargetHandle_t i_target )
- :IpmiFruInv(i_target)
-{
-
-};
-
-errlHndl_t systemFwIpmiFruInv::buildInternalUseArea(std::vector<uint8_t>
- &io_data)
-{
- //This section not needed for system firmware type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t systemFwIpmiFruInv::buildChassisInfoArea(std::vector<uint8_t>
- &io_data)
-{
- //This section not needed for system firmware type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t systemFwIpmiFruInv::buildBoardInfoArea(std::vector<uint8_t> &io_data)
-{
- //This section not needed for system firmware type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t systemFwIpmiFruInv::buildProductInfoArea(std::vector<uint8_t>
- &io_data)
-{
- errlHndl_t l_errl = NULL;
-
- do {
- //Set formatting data that goes at the beginning of the record
- preFormatProcessing(io_data, true);
-
- uint8_t l_data[] = {IPMIFRUINV::TYPELENGTH_BYTE_NULL,
- IPMIFRUINV::TYPELENGTH_BYTE_ASCII + 18, 'O','p','e',
- 'n','P','O','W','E','R',' ','F','i','r','m','w','a',
- 'r','e', IPMIFRUINV::TYPELENGTH_BYTE_NULL};
-
- io_data.insert( io_data.end(),
- &l_data[0],
- &l_data[0] + (uint8_t(sizeof(l_data) / sizeof(uint8_t))));
-
- //Get PNOR Version Here
- PNOR::SectionInfo_t l_pnorInfo;
- l_errl = getSectionInfo( PNOR::VERSION , l_pnorInfo);
- if (l_errl) { break; }
-
- uint8_t* l_versionData = reinterpret_cast<uint8_t*>( l_pnorInfo.vaddr );
- //Total Bytes in PNOR Version String
- uint8_t l_numBytes = 0;
- uint8_t l_curOffset = 0;
-
- //Total Number of fields needed to print PNOR Version String
- uint8_t l_numFields = 0;
- bool l_clearStandardFields = true;
-
- //First determine number of bytes in PNOR Version string
- // with the caveat there is a max record size allowed, so
- // the string will be cut off if too long
- //Also, remove newline chars
- while ((l_numBytes < IPMIFRUINV::MAX_RECORD_SIZE -
- (uint8_t(sizeof(l_data) / sizeof(uint8_t))) -
- IPMIFRUINV::COMMON_HEADER_FORMAT_SIZE - 8)
- && (((char)(l_versionData[l_numBytes])) != '\0'))
- {
-
- if (((char)(l_versionData[l_numBytes])) == '\n')
- {
-
- if (l_numBytes > l_curOffset)
- {
- //Add on size of this field to the data buffer
- io_data.push_back(
- IPMIFRUINV::TYPELENGTH_BYTE_ASCII
- + (l_numBytes-l_curOffset));
-
- io_data.insert(io_data.end(),
- &l_versionData[0]+(l_curOffset),
- &l_versionData[0]+(l_numBytes));
- }
-
- //Null data for standard fields needs to be indicated once after
- // the first segment of data is displayed to match the
- // ipmi fru spec
- if (l_clearStandardFields)
- {
- //Add Empty Asset Tag
- io_data.push_back(uint8_t(0));
- //FRU File ID - Empty
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
- io_data.push_back(uint8_t(0)); // Empty FRU File ID bytes
- l_clearStandardFields = false;
- }
-
- //Increment past the newline char
- l_curOffset = l_numBytes + 1;
- }
- l_numBytes++;
- }
-
- if (l_curOffset == 0)
- {
- //Calculate the number of fields required to display this data
- // given only MAX_ASCII_FIELD_SIZE bytes can be in any one given
- // IPMI fru inventory field
- l_numFields = l_numBytes / IPMIFRUINV::MAX_ASCII_FIELD_SIZE;
- if (l_numBytes % IPMIFRUINV::MAX_ASCII_FIELD_SIZE)
- {
- l_numFields += 1;
- }
-
- //Count by number of fields, adding the data to the buffer as
- // we go.
- for (uint8_t i=0; i < l_numFields; i++)
- {
- //Determine the data size for this particular field
- uint8_t l_dataSize=IPMIFRUINV::MAX_ASCII_FIELD_SIZE;
- if (i == l_numFields - 1)
- {
- l_dataSize = l_numBytes -
- (i * IPMIFRUINV::MAX_ASCII_FIELD_SIZE);
- }
-
- //Add on size of this field to the data buffer
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_ASCII
- + l_dataSize);
-
- //Insert this segment of version string data
- io_data.insert(io_data.end(),
- &l_versionData[0]+(i * IPMIFRUINV::MAX_ASCII_FIELD_SIZE),
- &l_versionData[0]+(i * IPMIFRUINV::MAX_ASCII_FIELD_SIZE)
- +l_dataSize);
-
- //Null data for standard fields needs to be indicated once after
- // the first segment of data is displayed to match the
- // ipmi fru spec
- if (l_clearStandardFields)
- {
- //Add Empty Asset Tag
- io_data.push_back(uint8_t(0));
- //FRU File ID - Empty
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
- l_clearStandardFields = false;
- }
-
- }
- }
- else
- {
- if (l_numBytes > l_curOffset)
- {
- io_data.push_back( IPMIFRUINV::TYPELENGTH_BYTE_ASCII
- + (l_numBytes-l_curOffset));
-
- io_data.insert(io_data.end(),
- &l_versionData[0]+(l_curOffset),
- &l_versionData[0]+(l_numBytes));
- }
-
- }
-
- if (l_clearStandardFields)
- {
- //Add Asset Tag
- io_data.push_back(uint8_t(0)); //No Asset Tag needed - O bytes
- //FRU File ID - Empty
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
- }
-
- io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
-
- } while(0);
-
- //Finalize section formatting
- postFormatProcessing(io_data);
-
- return l_errl;
-}
-
-errlHndl_t systemFwIpmiFruInv::buildMultiRecordInfoArea(std::vector<uint8_t>
- &io_data)
-{
- //This section not needed for system firmware type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-//##############################################################################
-membufIpmiFruInv::membufIpmiFruInv( TARGETING::TargetHandle_t i_target,
- TARGETING::TargetHandleList i_extraTargets,
- bool i_isUpdate)
- :IpmiFruInv(i_target),
- iv_isUpdate(i_isUpdate),
- iv_extraTargets(i_extraTargets)
-{
-};
-
-errlHndl_t membufIpmiFruInv::buildInternalUseArea(
- std::vector<uint8_t> &io_data)
-{
- //This section not needed for the mem buf type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t membufIpmiFruInv::buildChassisInfoArea(
- std::vector<uint8_t> &io_data)
-{
- //This section not needed for the mem buf type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t membufIpmiFruInv::buildBoardInfoArea(
- std::vector<uint8_t> &io_data)
-{
- errlHndl_t l_errl = NULL;
-
- do {
- //Set formatting data that goes at the beginning of the record
- preFormatProcessing(io_data, true);
-
- // Set Mfg Build date
- // Grab VPD data into seperate data vector
- std::vector<uint8_t> mfgDateData;
- l_errl = addVpdData(mfgDateData, PVPD::OPFR, PVPD::MB, false, false);
- if (l_errl) { break; }
-
- // Pass that to the function that sets the Build date
- setMfgData(io_data, mfgDateData);
-
- uint8_t l_fru_id = 0xFF;
- // if the centaur_ecid_fru_id is not valid then the centaur is on a
- // riser card, grab its vpd and populate the record
- l_fru_id = iv_target->getAttr<TARGETING::ATTR_CENTAUR_ECID_FRU_ID>();
-
- if( l_fru_id == 0xFF )
- {
- //Set Vendor Name - ascii formatted data
- l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::VN, true);
- if (l_errl) { break; }
-
- //Set Product Name - ascii formatted data
- l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::DR, true);
- if (l_errl) { break; }
-
- //Set Product Serial number - ascii formatted data
- TARGETING::ATTR_SERIAL_NUMBER_type l_sn = {'0'};
- if( !( iv_target->
- tryGetAttr<TARGETING::ATTR_SERIAL_NUMBER>
- ( l_sn) ) )
- {
- // Should not fail. Need to use tryGetAttr due to complex type.
- // Use zeros if fails.
- TRACFCOMP(g_trac_ipmi,"membufIpmiFruInv::buildBoardInfoArea - "
- "Error getting serial number attribute");
- }
- // The attribute size is 18. The vpd is 16. Only use 16.
- addCommonAttrData(io_data,
- (uint8_t *)&l_sn,
- VPD_SN_PN_VPD_SIZE);
-
- //Set Product Part number - ascii formatted data
- TARGETING::ATTR_PART_NUMBER_type l_pn = {'0'};
- if( !( iv_target->
- tryGetAttr<TARGETING::ATTR_PART_NUMBER>
- ( l_pn) ) )
- {
- // Should not fail. Need to use tryGetAttr due to complex type.
- // Use zeros if fails.
- TRACFCOMP(g_trac_ipmi,"membufIpmiFruInv::buildBoardInfoArea - "
- "Error getting part number attribute");
- }
- // The attribute size is 18. The vpd is 16. Only use 16.
- addCommonAttrData(io_data,
- (uint8_t *)&l_pn,
- VPD_SN_PN_VPD_SIZE);
-
- //Push Fru File ID Byte - NULL
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
-
- }
- else
- {
- //Set Vendor Name - NULL
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
-
- //Set Product Name - NULL
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
-
- //Set Product Serial number - NULL
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
-
- //Set Product Part number - NULL
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
-
- //Push Fru File ID Byte - NULL
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
-
- }
-
- //Only set the ECID Data during an update scenario
- if (iv_isUpdate == true)
- {
- customData (iv_extraTargets, io_data);
- }
-
- //Indicate End of Custom Fields
- io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
-
- } while (0);
-
- //Complete record data formatting
- postFormatProcessing(io_data);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,"membufIpmiFruInv::buildBoardInfoArea - "
- "Errors collecting board info data");
- }
-
- return l_errl;
-}
-
-errlHndl_t membufIpmiFruInv::buildProductInfoArea(
- std::vector<uint8_t> &io_data)
-{
- //This section not needed for the mem buf type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t membufIpmiFruInv::buildMultiRecordInfoArea(
- std::vector<uint8_t> &io_data)
-{
- //This section not needed for the mem buf type
- return IpmiFruInv::buildEmptyArea(io_data);
-}
-
-errlHndl_t membufIpmiFruInv::addVpdData(std::vector<uint8_t> &io_data,
- uint8_t i_record,
- uint8_t i_keyword,
- bool i_ascii,
- bool i_typeLengthByte)
-{
- errlHndl_t l_errl = NULL;
-
- l_errl = addCommonVpdData(iv_target,
- io_data,
- DeviceFW::CVPD,
- i_record,
- i_keyword,
- i_ascii,
- i_typeLengthByte);
- return l_errl;
-}
-//##############################################################################
-void IpmiFruInv::customData(TARGETING::TargetHandleList i_extraTargets,
- std::vector<uint8_t> &io_data)
-{
-
- bool l_setCustomData = false;
- // Check if we should add ECID
- for (TARGETING::TargetHandleList::const_iterator extraTargets_it =
- i_extraTargets.begin();
- extraTargets_it != i_extraTargets.end();
- ++extraTargets_it
- )
- {
- TARGETING::TargetHandle_t l_extraTarget = *extraTargets_it;
-
- //If we're in an update and the target is a membuf, we update the ecid.
- if ( l_extraTarget->getAttr<TARGETING::ATTR_TYPE>() ==
- TARGETING::TYPE_MEMBUF)
- {
- TARGETING::ATTR_ECID_type ecidInfo;
- bool getEcid =
- l_extraTarget->tryGetAttr<TARGETING::ATTR_ECID>(ecidInfo);
- if (getEcid)
- {
- l_setCustomData = true;
- addEcidData(l_extraTarget, ecidInfo, io_data);
- }
- else
- {
- TRACFCOMP(g_trac_ipmi, "No ECID info for this huid 0x%x",
- TARGETING::get_huid(l_extraTarget));
- }
- }
- }
-
- //If no Custom data was sent, an Empty Byte is needed
- if (!l_setCustomData)
- {
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
- }
-}
-
-void IpmiFruInv::addEcidData(const TARGETING::TargetHandle_t& i_target,
- const TARGETING::ATTR_ECID_type& i_ecidInfo,
- std::vector<uint8_t> &io_data)
-{
- // Create Custom ECID Field
- // - First put in 'ECID:' to make it obvious what this is
- uint8_t l_data[] = {IPMIFRUINV::TYPELENGTH_BYTE_ASCII + 37,'E','C','I','D',
- ':'};
-
- // @todo-RTC:124687 - Refactor multiple reallocations
- io_data.insert( io_data.end(),
- &l_data[0],
- &l_data[0] + (uint8_t(sizeof(l_data) / sizeof(uint8_t))));
-
- CPPASSERT(sizeof(ATTR_ECID_type) == 16);
- CPPASSERT((sizeof(i_ecidInfo) / sizeof(ATTR_ECID_type)) == 2);
-
- char l_ecidAscii[33];
- sprintf(l_ecidAscii, "%.16llX%.16llX", i_ecidInfo[0], i_ecidInfo[1]);
-
- uint8_t* l_vDataPtr = (uint8_t*) &l_ecidAscii[0];
- io_data.insert(io_data.end(), &l_vDataPtr[0], &l_vDataPtr[0]+32);
-
- return;
-}
-
-void IpmiFruInv::addECData(const TARGETING::TargetHandle_t& i_target,
- const TARGETING::ATTR_EC_type& i_ecInfo,
- std::vector<uint8_t> &io_data)
-{
- // Create Custom EC Field
- // - First put in 'EC:' to make it obvious what this is
- uint8_t l_data[] = {IPMIFRUINV::TYPELENGTH_BYTE_ASCII + 5,'E','C',':'};
-
- // @todo-RTC:124687 - Refactor multiple reallocations
- io_data.insert( io_data.end(),
- &l_data[0],
- &l_data[0] + (uint8_t(sizeof(l_data) / sizeof(uint8_t))));
-
- CPPASSERT(sizeof(ATTR_EC_type) == 1);
- CPPASSERT((sizeof(i_ecInfo) / sizeof(ATTR_EC_type)) == 1);
-
- char l_ecAscii[3];
- sprintf(l_ecAscii,"%X",i_ecInfo);
-
- io_data.insert(io_data.end(), &l_ecAscii[0],&l_ecAscii[2]);
-
- return;
-}
-
-errlHndl_t IpmiFruInv::addCommonVpdData(
- const TARGETING::TargetHandle_t& i_target,
- std::vector<uint8_t> &io_data,
- DeviceFW::AccessType i_accessType,
- uint8_t i_record,
- uint8_t i_keyword,
- bool i_ascii,
- bool i_typeLengthByte)
-{
- size_t l_vpdSize = 0;
- errlHndl_t l_errl = NULL;
-
- do {
- // First get size with NULL call:
- // Bypass DEVICE_?VPD_ADDRESS inorder to maximize common code
- l_errl = deviceRead(i_target,
- NULL,
- l_vpdSize,
- i_accessType,
- i_record,
- i_keyword,
- VPD::AUTOSELECT);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,"addCommonVpdData - Error "
- "while reading keyword size");
- break;
- }
-
- //Assert if vpd field is too large to fit in IPMI fru inventory format
- assert(l_vpdSize < IPMIFRUINV::TYPELENGTH_BYTE_ASCII);
-
- if (l_vpdSize > 0)
- {
- uint8_t l_offset = 0;
- //Add on the typelength byte if requested
- if (i_typeLengthByte)
- {
- //Determine how big data is and expand it to handle the soon to
- //be read VPD data
- l_offset = io_data.size();
- io_data.resize(l_offset + 1 + l_vpdSize);
- //Add on the data to the type/length byte indicating it is ascii
- // otherwise leave it as binary
- if (i_ascii)
- {
- io_data.at(l_offset) = l_vpdSize
- + IPMIFRUINV::TYPELENGTH_BYTE_ASCII;
- }
- else
- {
- io_data.at(l_offset) = l_vpdSize;
- }
- l_offset += 1;
- }
- else
- {
- //Determine how big data is and expand it to handle the soon to
- //be read VPD data
- l_offset = io_data.size();
- io_data.resize(l_offset + l_vpdSize);
- }
- //Read the VPD data directly into fru inventory data buffer
- l_errl = deviceRead(i_target,
- &io_data[l_offset],
- l_vpdSize,
- i_accessType,
- i_record,
- i_keyword,
- VPD::AUTOSELECT);
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"addCommonVpdData - "
- " No size returned for keyword");
- }
- } while(0);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi, "addCommonVpdData - Error "
- "acquiring data from Vpd.");
- }
-
- return l_errl;
-}
-
-void IpmiFruInv::addCommonAttrData( std::vector<uint8_t> &io_data,
- uint8_t * i_pAttrData,
- size_t i_length)
-{
- uint8_t l_offset = io_data.size();
-
- //Determine how big data is and expand it to handle the attr data
- //and the typelength byte
- io_data.resize(l_offset + 1 + i_length);
-
- //Add the type/length byte indicating ascii data.
- io_data.at(l_offset) = i_length + IPMIFRUINV::TYPELENGTH_BYTE_ASCII;
-
- //copy attr data
- memcpy (&io_data[l_offset+1],i_pAttrData,i_length);
-}
-
-
-void IPMIFRUINV::clearData(uint8_t i_fruId)
-{
- uint8_t l_clearData[] =
- {IPMIFRUINV::RECORD_NOT_PRESENT, IPMIFRUINV::RECORD_NOT_PRESENT,
- IPMIFRUINV::RECORD_NOT_PRESENT, IPMIFRUINV::RECORD_NOT_PRESENT,
- IPMIFRUINV::RECORD_NOT_PRESENT, IPMIFRUINV::RECORD_NOT_PRESENT,
- IPMIFRUINV::RECORD_NOT_PRESENT, IPMIFRUINV::RECORD_NOT_PRESENT};
-
- //Use IMPIFRU::writeData to send data to service processor
- IPMIFRU::writeData(i_fruId, l_clearData,
- IPMIFRUINV::COMMON_HEADER_FORMAT_SIZE,
- IPMIFRUINV::DEFAULT_FRU_OFFSET);
-}
-
-void IPMIFRUINV::setData(bool i_updateData)
-{
- errlHndl_t l_errl = NULL;
-
- do
- {
- // find CLASS_SYS (the top level target)
- TARGETING::Target* pSys;
- TARGETING::targetService().getTopLevelTarget(pSys);
-
- if (!(pSys))
- {
- TRACFCOMP(g_trac_ipmi,"IPMIFRUINV::setData - No CLASS_SYS TopLevelTarget found:"
- " not setting IPMI Fru Inventory");
- break;
- }
-
- //Container with list of frus and a boolean indicating whether the data
- //needs to be cleared or not
- // @todo-RTC:124687 - Refactor map use
- std::map<uint8_t,bool> frusToClear;
- //List of all potential Frus that could need IPMI Fru Inv. Data Sent
- std::vector< std::pair<TARGETING::TargetHandle_t, uint8_t> >
- l_potentialFrus;
-
- if (i_updateData == false)
- {
- IPMIFRUINV::gatherClearData(pSys, frusToClear);
- }
-
- //Get System FW FRU_ID if available
- uint32_t l_systemFwFruId;
- bool hasSystemFwFruId =
- pSys->tryGetAttr<TARGETING::ATTR_BMC_FRU_ID>(l_systemFwFruId);
- if (hasSystemFwFruId)
- {
- l_potentialFrus.push_back(std::make_pair(pSys, l_systemFwFruId));
- }
-
- // Find list of all target types that may need a fru inv. record set
- IPMIFRUINV::gatherSetData(pSys, frusToClear,
- l_potentialFrus, i_updateData);
-
- //Now Loop through all TargetHandle_t, uint8_t pairs to see if there are
- //multiple targets with the same fruId. These will be formed into a list
- //as data from all Targets will be combined into one IPMI Fru Inventory
- //Record under the same fruId.
- std::vector<std::pair<TARGETING::TargetHandle_t,uint8_t> >::iterator
- l_iter;
-
- for (l_iter = l_potentialFrus.begin(); l_iter != l_potentialFrus.end();
- ++l_iter)
- {
- //iterators to walk list and group frus together
- std::vector<std::pair<TARGETING::TargetHandle_t,uint8_t> >::iterator
- l_curPair = l_iter;
- std::vector<std::pair<TARGETING::TargetHandle_t,uint8_t> >::iterator
- l_nextPair = l_iter;
-
- //The 'base' TargetHandleList will have one FRU
- TARGETING::TargetHandleList l_curFru;
- l_curFru.push_back(l_curPair->first);
- //This will be the fruId to compare with what comes after this
- //Target in the vector
- uint8_t l_fruId = l_curPair->second;
-
- TRACFCOMP(g_trac_ipmi, "IPMIFRUINV::setData - Collecting all IPMI FRU Inventory Targets with fruId: [%08x]",
- l_fruId);
-
- ++l_nextPair;
- for( ; l_nextPair != l_potentialFrus.end()
- && l_nextPair->second == l_fruId; ++l_nextPair)
- {
- l_curFru.push_back(l_nextPair->first);
- l_iter = l_nextPair;
- }
- IpmiFruInv *l_fru = IpmiFruInv::Factory(l_curFru, i_updateData);
-
- if (l_fru != NULL)
- {
- //Target recognized, build & send IPMI FRU Invenotry record
- l_errl = l_fru->buildFruInvRecord();
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi, "IPMIFRUINV::setData - Errors encountered, will skip setting the rest of the data");
- break;
- }
- TRACFCOMP(g_trac_ipmi, "IPMIFRUINV::setData - Sending IPMI FRU Inventory Data for target with fruId: [%08x] and size [%08x]",
- l_fruId, l_curFru.size());
- l_fru->sendFruData(l_fruId);
- delete l_fru;
- l_fru = nullptr;
- }
- }
-
- //Do not clear data during a data update
- if (i_updateData == false)
- {
- //Now clear any FRU Data for fruIds that didn't have data set. This
- //will handle the case where something was removed from the system
- for (std::map<uint8_t,bool>::iterator it=frusToClear.begin();
- it!=frusToClear.end();
- ++it)
- {
- //If the bool is true its data needs to be cleared
- if (it->second == true)
- {
- IPMIFRUINV::clearData(it->first);
- }
- }
-
- // Only send GPU sensor PRESENT status one time (no update),
- // then allow HTMGT to update
-
- // Go through processors and send GPU sensor status
- // Get all Proc targets
- TARGETING::TargetHandleList l_procTargetList;
- getAllChips(l_procTargetList, TARGETING::TYPE_PROC);
-
- uint32_t gpu_sensors[SENSOR::MAX_GPU_SENSORS_PER_PROCESSOR];
- uint8_t num_valid_sensors = 0;
- for (const auto & l_procChip: l_procTargetList)
- {
- // report present GPU sensors
- l_errl = SENSOR::getGpuSensors( l_procChip,
- HWAS::GPU_FUNC_SENSOR,
- num_valid_sensors,
- gpu_sensors );
- if (!l_errl)
- {
- // build up present GPUs based on sensor data returned
- SENSOR::StatusSensor::statusEnum
- gpu_status[SENSOR::MAX_PROCESSOR_GPUS];
-
- // initialize to NOT PRESENT
- for (uint8_t j = 0; j < SENSOR::MAX_PROCESSOR_GPUS; j++)
- {
- gpu_status[j] =
- SENSOR::StatusSensor::statusEnum::NOT_PRESENT;
- }
-
- // now change the PRESENT ones
- for (uint8_t i = 0;
- i < SENSOR::MAX_GPU_SENSORS_PER_PROCESSOR; i++)
- {
- if (i < SENSOR::MAX_PROCESSOR_GPUS)
- {
- if (gpu_sensors[i] !=
- TARGETING::UTIL::INVALID_IPMI_SENSOR)
- {
- gpu_status[i] =
- SENSOR::StatusSensor::statusEnum::PRESENT;
- }
- }
- else
- {
- break;
- }
- }
-
- // Send the present/non-present GPU sensors
- SENSOR::updateGpuSensorStatus( l_procChip, gpu_status);
- }
- }
- }
-
- } while(0);
-
- if (l_errl)
- {
- //Commit errorlog encountered indicating there were issues
- //setting the FRU Inventory Data
- TRACFCOMP(g_trac_ipmi, "Errors encountered setting Fru Inventory Data");
- l_errl->collectTrace(IPMI_COMP_NAME);
- errlCommit(l_errl, IPMI_COMP_ID);
- }
- return;
-}
-
-void IPMIFRUINV::readFruData(uint8_t i_deviceId, uint8_t *o_data)
-{
- //Use IMPIFRU::readData to send data to service processor
- // it will do any error handling and memory management
- IPMIFRU::readData(i_deviceId, o_data);
-}
-
-char * IPMIFRUINV::getProductSN(uint8_t i_deviceId)
-{
- //If we cannot read the product serial number, default is 0's (set below)
- char * l_prodSN = NULL;
-
- //First read the entire record that contains the SN
- uint8_t *l_record = new uint8_t[IPMIFRU::MAX_RECORD_SIZE];
- memset(l_record, 0, IPMIFRU::MAX_RECORD_SIZE);
- readFruData(i_deviceId, l_record);
-
- do {
-
- //Code only supports version 1 of the FRU spec if for whatever reason
- // we didn't get data, this would be 0
- if (l_record[IPMIFRUINV::HEADER_FORMART_VERSION]
- != IPMIFRUINV::SPEC_VERSION)
- {
- TRACFCOMP(g_trac_ipmi, "FW does not support IPMI FRU Version: %d",
- l_record[1]);
- break;
- }
-
- //Get the offset in the record pointed to the product info area
- // (where the SN is located)
- uint8_t l_prodInfoOffset = l_record[IPMIFRUINV::PRODUCT_INFO_AREA];
-
- if (l_prodInfoOffset == IPMIFRUINV::RECORD_NOT_PRESENT)
- {
- TRACFCOMP(g_trac_ipmi, "Product Info Area Not present "
- "- returning empty SN");
- break;
- }
-
- //Start at the beginning of the Product Info Record and traverse to the
- // serial number entry
- uint8_t l_prodIndex = l_prodInfoOffset * RECORD_UNIT_OF_MEASUREMENT;
- l_prodIndex += 3; //Version, Length Byte, Language Code
-
- //MFG NAME Length + TYPELENGTH Byte
- l_prodIndex += ((TYPELENGTH_SIZE_MASK&l_record[l_prodIndex]) + 1);
-
- //Prod NAME Length + TYPELENGTH Byte
- l_prodIndex += ((TYPELENGTH_SIZE_MASK&l_record[l_prodIndex]) + 1);
-
- //Prod Part/Model Number Length + TYPELENGTH Byte
- l_prodIndex += ((TYPELENGTH_SIZE_MASK&l_record[l_prodIndex]) + 1);
-
- //Prod Version Length + TYPELEGNTH Byte
- l_prodIndex += ((TYPELENGTH_SIZE_MASK&l_record[l_prodIndex]) + 1);
-
- //Serial number located after Prod Version
- uint8_t l_prodSNOffset = l_prodIndex;
- uint8_t l_prodSNsize = TYPELENGTH_SIZE_MASK&l_record[l_prodSNOffset];
-
- //Grab Serial Number as char array
- l_prodSN = new char[l_prodSNsize+1];
- memcpy(l_prodSN, &l_record[l_prodSNOffset+1], l_prodSNsize);
- l_prodSN[l_prodSNsize] = '\0';
-
- //Can skip the rest.
-
- } while (0);
-
-
- delete[] l_record;
-
- return l_prodSN;
-}
-
-void IPMIFRUINV::gatherClearData(const TARGETING::Target* i_pSys,
- std::map<uint8_t,bool>& io_frusToClear)
-{
- TARGETING::PredicateCTM predChip(TARGETING::CLASS_CHIP);
- TARGETING::PredicateCTM predNode(TARGETING::CLASS_ENC,
- TARGETING::TYPE_NODE);
- TARGETING::PredicateCTM predDimm(TARGETING::CLASS_LOGICAL_CARD,
- TARGETING::TYPE_DIMM);
- TARGETING::PredicatePostfixExpr checkAllExpr;
- checkAllExpr.push(&predChip).push(&predNode).Or().push(&predDimm).Or();
- TARGETING::TargetHandleList l_allPossibleFrus;
- TARGETING::targetService().getAssociated( l_allPossibleFrus, i_pSys,
- TARGETING::TargetService::CHILD, TARGETING::TargetService::ALL,
- &checkAllExpr );
-
- for (TARGETING::TargetHandleList::const_iterator pTarget_it =
- l_allPossibleFrus.begin();
- pTarget_it != l_allPossibleFrus.end();
- ++pTarget_it)
- {
- TARGETING::TargetHandle_t pTarget = *pTarget_it;
- uint32_t l_fruId = pTarget->getAttr<TARGETING::ATTR_FRU_ID>();
-
- if (l_fruId)
- {
- //Assume we clear all possible targets to start
- // @todo-RTC:124506 - New logic may be needed to clear all targets
- // after a code update
- io_frusToClear[l_fruId] = true;
- }
- }
-
- return;
-}
-
-void IPMIFRUINV::gatherSetData(const TARGETING::Target* i_pSys,
- std::map<uint8_t,bool>& io_frusToClear,
- std::vector< std::pair<TARGETING::TargetHandle_t, uint8_t> >&
- io_potentialFrus,
- bool i_updateData)
-{
- TARGETING::PredicateCTM predChip(TARGETING::CLASS_CHIP);
- TARGETING::PredicateCTM predDimm(TARGETING::CLASS_LOGICAL_CARD,
- TARGETING::TYPE_DIMM);
- TARGETING::PredicatePostfixExpr checkExpr;
- TARGETING::PredicateHwas l_present;
- // @todo-RTC:124553 - Additional logic for deconfigured Frus
- // may be needed
- l_present.present(true);
-
- checkExpr.push(&predChip);
- TARGETING::PredicateCTM predNode(TARGETING::CLASS_ENC,
- TARGETING::TYPE_NODE);
- checkExpr.push(&predNode).Or();
-
- //When updating data on a later pass ignore dimms
- if (i_updateData)
- {
- checkExpr.push(&l_present).And();
- }
- else
- {
- checkExpr.push(&predDimm).Or().push(&l_present).And();
- }
-
- TARGETING::TargetHandleList pCheckPres;
- TARGETING::targetService().getAssociated( pCheckPres, i_pSys,
- TARGETING::TargetService::CHILD, TARGETING::TargetService::ALL,
- &checkExpr );
-
- for (TARGETING::TargetHandleList::const_iterator pTarget_it =
- pCheckPres.begin();
- pTarget_it != pCheckPres.end();
- ++pTarget_it
- )
- {
-
- TARGETING::TargetHandle_t pTarget = *pTarget_it;
- uint32_t l_fruId = pTarget->getAttr<TARGETING::ATTR_FRU_ID>();
-
- // check if this is a membuf target, if it is and the special
- // attribute to say we want a separate fru entry for the centaur ecids
- // is populated, then we will push that ecid to the potential frus
- // list
-
- if (TARGETING::TYPE_MEMBUF == pTarget->getAttr<TARGETING::ATTR_TYPE>())
- {
- uint8_t l_ecidFruId =
- pTarget->getAttr<TARGETING::ATTR_CENTAUR_ECID_FRU_ID>();
-
- // if the ecid fru id is valid use it, else use the regular fru id
- l_fruId = ( l_ecidFruId == 0xFF ) ? l_fruId : l_ecidFruId;
-
- TRACFCOMP(g_trac_ipmi,"l_fruId = 0x%x, l_ecidFruId = 0x%x", l_fruId, l_ecidFruId);
- }
-
- if (l_fruId)
- {
- //when updating data, ignore clearing data
- if (i_updateData == false)
- {
- //Indicate this fruId has data and later clear is not needed
- io_frusToClear[l_fruId] = false;
- }
- io_potentialFrus.push_back(std::make_pair(pTarget, l_fruId));
- }
- }
-
- //Sort the vector by FRU_ID for later use.
- //When the planar eeprom is shared for planar and memory buffer vpd, the
- //node and membuffs will have the same FRU ID. For this case, sort the Node
- //to be ahead of the mem buffs. The mem buffs will be extra targets for
- //their ECIDs.
- std::sort(io_potentialFrus.begin(),
- io_potentialFrus.end(),
- comparePairs);
-}
diff --git a/src/usr/ipmi/ipmifruinvprvt.H b/src/usr/ipmi/ipmifruinvprvt.H
deleted file mode 100644
index b7f0bf982..000000000
--- a/src/usr/ipmi/ipmifruinvprvt.H
+++ /dev/null
@@ -1,689 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmifruinvprvt.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-#ifndef __IPMI_IPMIFRUINVPRVT_H
-#define __IPMI_IMPIFRUINVPRVT_H
-
-namespace IPMIFRUINV
-{
- enum recordFields
- {
- //Storage Definition Headers will use version 1.2
- SPEC_VERSION = 1,
- RECORD_UNIT_OF_MEASUREMENT = 8, //size in bytes
- CHECKSUM_SIZE = 1, //size in bytes
- RECORD_NOT_PRESENT = 0,
- ENGLISH_LANGUAGE_CODE = 0,
- TYPELENGTH_BYTE_NULL = 0,
- TYPELENGTH_BYTE_ASCII = 0xC0,
- END_OF_CUSTOM_FIELDS = 0xC1,
- COMMON_HEADER_FORMAT_SIZE = 8, //size in bytes
- DEFAULT_CHASSIS_TYPE = 0x05,
- DEFAULT_FRU_OFFSET = 0,
- TYPELENGTH_SIZE_MASK = 0x3F, //bits 5:0 define num data bytes
- MAX_ASCII_FIELD_SIZE = 0x3F, //size in bytes
- MAX_RECORD_SIZE = 0xFF, //size in bytes
- };
-
- enum commonHeaderEntryOffsets
- {
- HEADER_FORMART_VERSION = 0,
- PRODUCT_INFO_AREA = 4,
- };
-
-};
-
-
-//Parent Class Contains all common functions to build up, format,
-// and send IPMI Fru Inventory Record Data
-//The parent Class also defines pure virtual functions so the child
-// is responsible to build up the individual record sections
-// as the data for those is specific to each child.
-class IpmiFruInv
-{
- public:
-
-
- /**
- * @brief Constructor
- *
- * @param[in] TargetHandle_t, Handle to target for which
- * to get relevant IPMI FRU Data from
- */
- IpmiFruInv(TARGETING::TargetHandle_t i_target);
-
- /**
- * @brief Default Destructor
- */
- virtual ~IpmiFruInv();
-
- /**
- * @brief Factory Pattern Creator function
- * @param[in] TargetHandle_t, Handle to target for which
- * to get relevant IPMI FRU Data from
- * @param[in] isUpdate, Indicator if the code is updating
- * existing data, or setting base data.
- */
- static IpmiFruInv *Factory(TARGETING::TargetHandleList i_targets,
- bool i_isUpdate);
-
- /**
- * @brief Package and send the IPMI FRU Data
- *
- * @param[in] uint8_t, IPMI Fru Device ID
- */
- void sendFruData(uint8_t i_deviceId);
-
- /**
- * @brief Gather and Format relevant IPMI Fru Inventory Data
- *
- * @param[in] void
- * @param[out] errlHndl_t, error encountered getting data
- */
- errlHndl_t buildFruInvRecord(void);
-
- protected:
- //The target to build an IPMI fru inventory record for
- TARGETING::TargetHandle_t iv_target;
-
- //The overall IPMI Fru Inventory record to send
- std::vector<uint8_t> iv_record_data;
-
- /**
- * @brief Format Beginning of Individual IPMI Fru Data Section
- *
- * @param[in/out] data, Data to be updated with formatting + header
- * @param[in] i_setLanguagCode, Indicator to set/not set Language Code
- */
- void preFormatProcessing(std::vector<uint8_t>& io_data,
- bool i_setLanguageCode);
-
- /**
- * @brief Format End of Individual IPMI Fru Data Section
- *
- * @param[in/out] data, Data container to be updated with formatting
- */
- void postFormatProcessing(std::vector<uint8_t>& io_data);
- /**
- * @brief Complete + Set size of Data Section
- *
- * @param[in/out] data, Data container with size to be updated
- * @param[in] offset, Indicate where to update size of data section
- */
- void setAreaSize(std::vector<uint8_t>& io_data, uint8_t i_offset);
-
- /**
- * @brief Add inputted data to overall IPMI Fru Record
- *
- * @param[in] data, Data container to be added to overall record
- */
- void addDataToRecord(const std::vector<uint8_t>& i_data);
-
- /**
- * @brief Format inpuuted data to hex data that contains build date info
- *
- * @param[in] mfgDateData, MFG date data container from VPD
- * @param[out] mfgDate, MFG date data value in minutes
- */
- errlHndl_t formatMfgData(std::vector<uint8_t> i_mfgDateData,
- uint32_t& o_mfgDate);
-
- /**
- * @brief Add product build date to IPMI fru record
- *
- * @param[in/out] data, The container to put build date in
- * @param[in] mfgDateData, MFG date data container from VPD
- */
- void setMfgData(std::vector<uint8_t> &io_data,
- std::vector<uint8_t> &i_mfgDateData);
-
- /**
- * @brief Builds the Internal Use Area Data Section
- * @param[in/out] data, The container to put intenral use area data in
- */
- virtual errlHndl_t buildInternalUseArea(std::vector<uint8_t> &io_data)=0;
-
- /**
- * @brief Builds the Chassis Info Area Data Section
- * @param[in/out] data, The container to put chassis info area data in
- */
- virtual errlHndl_t buildChassisInfoArea(std::vector<uint8_t> &io_data)=0;
-
- /**
- * @brief Builds the Board Info Area Data Section
- * @param[in/out] data, The container to put board info area data in
- */
- virtual errlHndl_t buildBoardInfoArea(std::vector<uint8_t> &io_data)=0;
-
- /**
- * @brief Builds the Product Info Area Data Section
- * @param[in/out] data, The container to put product info area data in
- */
- virtual errlHndl_t buildProductInfoArea(std::vector<uint8_t> &io_data)=0;
-
- /**
- * @brief Builds the MultiRecord Info Area Data Section
- * @param[in/out] data, The container to put multirecord info area data in
- */
- virtual errlHndl_t buildMultiRecordInfoArea(
- std::vector<uint8_t> &io_data)=0;
-
- /**
- * @brief Builds a standard data section that is empty
- * @param[in] data, The container to put the data in
- */
- virtual errlHndl_t buildEmptyArea(std::vector<uint8_t> &i_data);
-
- /**
- * @brief Debug function to print data to console
- * @param[in] data, The data to be printed
- */
- void printRecordDebugData(const std::vector<uint8_t> &i_data);
-
- /**
- * @brief Adds ECID attribute data
- * @param[in] target, The target to get the Sensor Number from
- * @param[in] ecid_info, The ECID attribute data
- * @param[in/out] data, The container to put ECID attribute data in
- */
- void addEcidData(const TARGETING::TargetHandle_t& i_target,
- const TARGETING::ATTR_ECID_type& i_ecidInfo,
- std::vector<uint8_t> &io_data);
-
- /**
- * @brief Adds EC attribute data
- * @param[in] target, The target to get the Sensor Number from
- * @param[in] ecInfo, The EC attribute data
- * @param[in/out] data, The container to put EC attribute data in
- */
- void addECData(const TARGETING::TargetHandle_t& i_target,
- const TARGETING::ATTR_EC_type& i_ecInfo,
- std::vector<uint8_t> &io_data);
- /**
- * @brief Adds Ecid and EC attribute data from extra targets as custom data
- * @param[in] TargetHandleList, Handle to list of extra
- * targets associated with this FRU Record
- * @param[in/out] data, The container to put ECID attribute data in
- */
- void customData(TARGETING::TargetHandleList i_extraTargets,
- std::vector<uint8_t> &io_data);
-
- /**
- * @brief Retrieve vpd record keyword and add to IPMI Fru Inventory record
- * @param[in/out] data, The container with record data
- * @param[in] access, Indicates vpd module to access (MVPD,PVPD,CPVD)
- * @param[in] record, Indicates major offset in the VPD to get more data
- * @param[in] keyword, Indicates minor offset in the VPD to get more data
- * @param[in] ascii, Indicates if VPD field is in ascii format or not
- */
- errlHndl_t addCommonVpdData(
- const TARGETING::TargetHandle_t& i_target,
- std::vector<uint8_t> &io_data,
- DeviceFW::AccessType i_accessType,
- uint8_t i_record,
- uint8_t i_keyword,
- bool i_ascii,
- bool i_typeLengthByte);
-
- /**
- * @brief Add attribute data to IPMI Fru Inventory record
- * @param[in/out] data, The container with record data
- * @param[in] attrData, Pointer to attribute data
- * @param[in] length, Length of data to add
- */
- void addCommonAttrData( std::vector<uint8_t> &io_data,
- uint8_t * i_pAttrData,
- size_t i_length);
-
- // The ATTR_SERIAL_NUMBER and ATTR_PART_NUMBER are 18 bytes but the
- // vpd data size is only 16. Only want to add the vpd data, not the pad.
- enum vpdSize
- {
- VPD_SN_PN_VPD_SIZE = 16,
- };
-
- // Store number of days in a each month for computation of build date
- const uint8_t daysInMonth[12] = {31, 28, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31};
-
- private:
- /**
- * @brief Compute and Add data checsum to data record
- *
- * @param[in/out] data, Data to be updated with checsum
- */
- void addDataChecksum(std::vector<uint8_t>& io_data);
-
- /**
- * @brief Pad data section to proper size
- *
- * @param[in/out] data, Data to be padded
- */
- void padData(std::vector<uint8_t>& io_data);
-
- /**
- * @brief Builds a section of the common header
- *
- * @param[in/out] data, Common Header section data container
- * @param[in] section_data, Data from one particular record section
- * @param[in/out] cur_offset, Current offset for data in overall record
- */
- void buildCommonHeaderSection(std::vector<uint8_t>& io_out_data,
- uint32_t i_section_data,
- uint32_t &io_cur_offset);
-
- /**
- * @brief Sets IPMI Fru Spec Revision Header Format Value
- *
- * @param[in/out] data, data to add format value to
- */
- void addHeaderFormat(std::vector<uint8_t>& io_data);
-
- /**
- * @brief Builds the common header data in iv_record
- *
- * @param[in] internal_use_data, IPMI internal use section data
- * @param[in] chassis_data, IPMI chassis section data
- * @param[in] board_data, IPMI board section data
- * @param[in] product_data, IPMI product section data
- * @param[in] multirecord_data, IPMI multirecord section data
- * @param[out] void
- */
- void buildCommonHeader( const std::vector<uint8_t> &i_internal_use_data,
- const std::vector<uint8_t> &i_chassis_data,
- const std::vector<uint8_t> &i_board_data,
- const std::vector<uint8_t> &i_product_data,
- const std::vector<uint8_t> &i_multirecord_data );
-
- /**
- * @brief Complete entire record by combining all data parts
- *
- * @param[in] internal_use_data, IPMI internal use section data
- * @param[in] chassis_data, IPMI chassis section data
- * @param[in] board_data, IPMI board section data
- * @param[in] product_data, IPMI product section data
- * @param[in] multirecord_data, IPMI multirecord section data
- */
- void completeRecord(const std::vector<uint8_t> &i_internal_use_data,
- const std::vector<uint8_t> &i_chassis_data,
- const std::vector<uint8_t> &i_board_data,
- const std::vector<uint8_t> &i_product_data,
- const std::vector<uint8_t> &i_multirecord_data);
-
-};
-
-
-//Child class for building up ISDimm Fru Inventory Record Data
-class isdimmIpmiFruInv : public IpmiFruInv
-{
-
- public:
-
- /**
- * @brief Constructor
- *
- * @param[in] TargetHandle_t, Handle to target for which
- * to get relevant IPMI FRU Data from
- */
- isdimmIpmiFruInv( TARGETING::TargetHandle_t i_target);
-
- /**
- * @brief Builds the Internal Use Area Data Section
- * @param[in/out] data, The container to put internal use area data in
- */
- errlHndl_t buildInternalUseArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Chassis Info Area Data Section
- * @param[in/out] data, The container to put chassis info area data in
- */
- errlHndl_t buildChassisInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Board Info Area Data Section
- * @param[in/out] data, The container to put board info area data in
- */
- errlHndl_t buildBoardInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Product Info Area Data Section
- * @param[in/out] data, The container to put product info area data in
- */
- errlHndl_t buildProductInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the MultiRecord Info Area Data Section
- * @param[in/out] data, The container to put multirecord info area data in
- */
- errlHndl_t buildMultiRecordInfoArea(std::vector<uint8_t> &io_data);
-
- private:
-
- /**
- * @brief Adds the specified VPD data to the data to build up a given
- * record
- * @param[in/out] data, The container with record data
- * @param[in] keyword, Indicates where in the VPD to get more data
- * @param[in] ascii, Indicates if VPD field is in ascii format or not
- */
- errlHndl_t addVpdData(std::vector<uint8_t> &io_data,
- uint8_t i_keyword,
- bool i_ascii=false);
-
- /**
- * @brief Add manufacturer name of memory module into IPMI message buffer.
- * @param[in/out] data, The container with record data
- * @return errlHndl_t, Error handle, NULL if operation was completed
- * successfully
- */
- errlHndl_t addSpdManufacturer(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Add detailed description of memory module into IPMI message buffer.
- * @param[in/out] data, The container with record data
- * @return errlHndl_t, Error handle, NULL if operation was completed
- * successfully
- */
- errlHndl_t addSpdDetails(std::vector<uint8_t> &io_data);
-
-};
-
-//Child class for building up Processor Fru Inventory Record Data
-class procIpmiFruInv : public IpmiFruInv
-{
-
- public:
-
- /**
- * @brief Constructor
- *
- * @param[in] TargetHandle_t, Handle to target for which
- * to get relevant IPMI FRU Data from
- * @param[in] isUpdate, Indicator if the code is updating
- * existing data, or setting base data.
- */
- procIpmiFruInv( TARGETING::TargetHandle_t i_target,
- bool i_isUpdate );
-
- /**
- * @brief Builds the Internal Use Area Data Section
- * @param[in/out] data, The container to put internal use area data in
- */
- errlHndl_t buildInternalUseArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Chassis Info Area Data Section
- * @param[in/out] data, The container to put chassis info area data in
- */
- errlHndl_t buildChassisInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Board Info Area Data Section
- * @param[in/out] data, The container to put board info area data in
- */
- errlHndl_t buildBoardInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Product Info Area Data Section
- * @param[in/out] data, The container to put product info area data in
- */
- errlHndl_t buildProductInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the MultiRecord Info Area Data Section
- * @param[in/out] data, The container to put multirecord info area data in
- */
- errlHndl_t buildMultiRecordInfoArea(std::vector<uint8_t> &io_data);
-
- protected:
-
- //Indicator if a data update is happening.
- //True - means we are solely updating certain data
- //False - means we are doing the initial 'base' data set
- bool iv_isUpdate;
-
- private:
-
- /**
- * @brief Adds the specified VPD data to the data to build up a given
- * IPMI Fru Inventory record
- * @param[in/out] data, The container with record data
- * @param[in] record, Indicates major offset in the VPD to get more data
- * @param[in] keyword, Indicates minor offset in the VPD to get more data
- * @param[in] ascii, Indicates if VPD field is in ascii format or not
- * @param[in] typeLengthBtye, Indicates whether type length to be added.
- */
- errlHndl_t addVpdData(std::vector<uint8_t> &io_data,
- uint8_t i_record,
- uint8_t i_keyword,
- bool i_ascii=false,
- bool i_typeLengthByte=true);
-
-};
-
-//Child class for building up backplane Fru Inventory Record Data
-class backplaneIpmiFruInv : public IpmiFruInv
-{
-
- public:
-
- /**
- * @brief Constructor
- *
- * @param[in] TargetHandle_t, Handle to target for which
- * to get relevant IPMI FRU Data from
- * @param[in] TargetHandleList, Handle to list of extra
- * targets associated with this FRU Record
- * @param[in] isUpdate, Indicator if the code is updating
- * existing data, or setting base data.
- */
- backplaneIpmiFruInv( TARGETING::TargetHandle_t i_target,
- TARGETING::TargetHandleList i_extraTargets,
- bool i_isUpdate );
-
- /**
- * @brief Builds the Internal Use Area Data Section
- * @param[in/out] data, The container to put internal use area data in
- */
- errlHndl_t buildInternalUseArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Chassis Info Area Data Section
- * @param[in/out] data, The container to put chassis info area data in
- */
- errlHndl_t buildChassisInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Board Info Area Data Section
- * @param[in/out] data, The container to put board info area data in
- */
- errlHndl_t buildBoardInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Product Info Area Data Section
- * @param[in/out] data, The container to put product info area data in
- */
- errlHndl_t buildProductInfoArea(std::vector<uint8_t>& io_data);
-
- /**
- * @brief Builds the MultiRecord Info Area Data Section
- * @param[in/out] data, The container to put multirecord info area data in
- */
- errlHndl_t buildMultiRecordInfoArea(std::vector<uint8_t>& io_data);
-
- protected:
- //Indicator if a data update is happening.
- //True - means we are solely updating certain data
- //False - means we are doing the initial 'base' data set
- bool iv_isUpdate;
-
- //The list of Extra Targets if multiple targets are
- //associated with one FRU_ID
- TARGETING::TargetHandleList iv_extraTargets;
-
- private:
-
- /**
- * @brief Adds the specified VPD data to the data to build up a given
- * IPMI Fru Inventory record
- * @param[in/out] data, The container with record data
- * @param[in] record, Indicates major offset in the VPD to get more data
- * @param[in] keyword, Indicates minor offset in the VPD to get more data
- * @param[in] ascii, Indicates if VPD field is in ascii format or not
- * @param[in] typeLengthBtye, Indicates whether type length to be added.
- */
- errlHndl_t addVpdData(std::vector<uint8_t> &io_data,
- uint8_t i_record,
- uint8_t i_keyword,
- bool i_ascii=false,
- bool i_typeLengthByte=true);
-};
-
-//Child class for building up System Firwmare Fru Inventory Record Data
-class systemFwIpmiFruInv : public IpmiFruInv
-{
-
- public:
- /**
- * @brief Constructor
- *
- * @param[in] TargetHandle_t, Handle to target for which
- * to get relevant IPMI FRU Data from
- */
- systemFwIpmiFruInv( TARGETING::TargetHandle_t i_target);
-
- /**
- * @brief Builds the Internal Use Area Data Section
- * @param[in/out] data, The container to put internal use area data in
- */
- errlHndl_t buildInternalUseArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Chassis Info Area Data Section
- * @param[in/out] data, The container to put chassis info area data in
- */
- errlHndl_t buildChassisInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Board Info Area Data Section
- * @param[in/out] data, The container to put board info area data in
- */
- errlHndl_t buildBoardInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Product Info Area Data Section
- * @param[in/out] data, The container to put product info area data in
- */
- errlHndl_t buildProductInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the MultiRecord Info Area Data Section
- * @param[in/out] data, The container to put multirecord info area data in
- */
- errlHndl_t buildMultiRecordInfoArea(std::vector<uint8_t> &io_data);
-
-};
-
-//Child class for building up membuf Fru Inventory Record Data. For example,
-//for a memory riser card Fru.
-class membufIpmiFruInv : public IpmiFruInv
-{
-
- public:
-
- /**
- * @brief Constructor
- *
- * @param[in] TargetHandle_t, Handle to target for which
- * to get relevant IPMI FRU Data from
- * @param[in] TargetHandleList, Handle to list of extra
- * targets associated with this FRU Record
- * @param[in] isUpdate, Indicator if the code is updating
- * existing data, or setting base data.
- */
- membufIpmiFruInv( TARGETING::TargetHandle_t i_target,
- TARGETING::TargetHandleList i_extraTargets,
- bool i_isUpdate );
-
- /**
- * @brief Builds the Internal Use Area Data Section
- * @param[in/out] data, The container to put internal use area data in
- */
- errlHndl_t buildInternalUseArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Chassis Info Area Data Section
- * @param[in/out] data, The container to put chassis info area data in
- */
- errlHndl_t buildChassisInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Board Info Area Data Section
- * @param[in/out] data, The container to put board info area data in
- */
- errlHndl_t buildBoardInfoArea(std::vector<uint8_t> &io_data);
-
- /**
- * @brief Builds the Product Info Area Data Section
- * @param[in/out] data, The container to put product info area data in
- */
- errlHndl_t buildProductInfoArea(std::vector<uint8_t>& io_data);
-
- /**
- * @brief Builds the MultiRecord Info Area Data Section
- * @param[in/out] data, The container to put multirecord info area data in
- */
- errlHndl_t buildMultiRecordInfoArea(std::vector<uint8_t>& io_data);
-
- protected:
- //Indicator if a data update is happening.
- //True - means we are solely updating certain data
- //False - means we are doing the initial 'base' data set
- bool iv_isUpdate;
-
- //The list of Extra Targets if multiple targets are
- //associated with one FRU_ID
- TARGETING::TargetHandleList iv_extraTargets;
-
- private:
-
- /**
- * @brief Adds the specified VPD data to the data to build up a given
- * IPMI Fru Inventory record
- * @param[in/out] data, The container with record data
- * @param[in] record, Indicates major offset in the VPD to get more data
- * @param[in] keyword, Indicates minor offset in the VPD to get more data
- * @param[in] ascii, Indicates if VPD field is in ascii format or not
- * @param[in] typeLengthBtye, Indicates whether type length to be added.
- */
- errlHndl_t addVpdData(std::vector<uint8_t> &io_data,
- uint8_t i_record,
- uint8_t i_keyword,
- bool i_ascii=false,
- bool i_typeLengthByte=true);
-
-};
-
-#endif
diff --git a/src/usr/ipmi/ipmimsg.C b/src/usr/ipmi/ipmimsg.C
deleted file mode 100644
index 4d00d1922..000000000
--- a/src/usr/ipmi/ipmimsg.C
+++ /dev/null
@@ -1,69 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmimsg.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file ipmimsg.C
- * @brief code for the IPMI message class
- */
-
-#include <errl/errlmanager.H>
-
-#include "ipmimsg.H"
-
-#include <kernel/console.H>
-#include <config.h>
-
-// Defined in ipmidd.C
-extern trace_desc_t * g_trac_ipmi;
-#define IPMI_TRAC(printf_string,args...) \
- TRACFCOMP(g_trac_ipmi,"msg: " printf_string,##args)
-
-namespace IPMI
-{
-
- ///
- /// @brief msg ctor
- /// @param[in] i_cmd, the network function & command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (new'd space)
- ///
- Message::Message(const command_t& i_cmd,
- const uint8_t i_len,
- uint8_t* i_data):
- iv_msg(msg_allocate()),
- iv_key(0),
- iv_len(i_len),
- iv_netfun(i_cmd.first),
- iv_seq(iv_key),
- iv_cmd(i_cmd.second),
- iv_cc(0),
- iv_state(0),
- iv_errl(NULL),
- iv_data(i_data)
- {
- iv_timeout.tv_sec = 0;
- iv_timeout.tv_nsec = 0;
- }
-
-};
diff --git a/src/usr/ipmi/ipmimsg.H b/src/usr/ipmi/ipmimsg.H
deleted file mode 100644
index b7f6d966e..000000000
--- a/src/usr/ipmi/ipmimsg.H
+++ /dev/null
@@ -1,133 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmimsg.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2015 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-#ifndef __IPMI_IPMIMSG_H
-#define __IPMI_IPMIMSG_H
-
-#include <time.h>
-#include <map>
-#include <list>
-#include <sys/msg.h>
-#include <errl/errlentry.H>
-#include <ipmi/ipmiif.H>
-
-namespace IPMI
-{
- typedef std::list<msg_t*> send_q_t;
- typedef std::list<msg_t*> timeout_q_t;
- typedef std::map<uint8_t, msg_t*> respond_q_t;
- typedef std::map<uint8_t, msg_q_t> event_q_t;
-
- // IPMI message base class. A thing which expects to be sent down a
- // msg_q (so has a msg_t) and defines operations performed by a generic
- // IPMI resource manager. Details are left to the subclasses.
- class Message
- {
- public:
- ///
- /// @brief static factory
- /// @param[in] i_cmd, the network functon & command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (allocated space)
- /// @param[in] i_type, synchronous or async
- ///
- /// @return a pointer to a new'd Message object
- ///
- static Message* factory(const command_t& i_cmd = no_command(),
- const uint8_t i_len = 0,
- uint8_t* i_data = NULL,
- const message_type i_type = TYPE_SYNC);
-
- ///
- /// @brief Message ctor
- /// @param[in] i_cmd, the network functon & command
- /// @param[in] i_len, the length of the data
- /// @param[in] i_data, the data (allocated space)
- ///
- Message(const command_t& i_cmd = no_command(),
- const uint8_t i_len = 0,
- uint8_t* i_data = NULL);
-
- ///
- /// @brief Message dtor
- ///
- virtual ~Message(void)
- {
- // Do NOT delete[] iv_data here. For synchronous messages
- // the caller wants this data and expects to delete[] it
- // itself. For async messages it is deleted in the dtor
- msg_free(iv_msg);
- }
-
- ///
- /// @brief the header size of a message for the underlying transport
- /// @param void
- /// @return size_t, the header size
- ///
- virtual size_t header_size(void) = 0;
-
- ///
- /// @brief transmit a message.
- /// @return true iff there was no transmission error
- ///
- virtual bool xmit(void) = 0;
-
- ///
- /// @brief complete the processing when a response arrives
- /// @return void
- ///
- virtual void response(msg_q_t i_msgQ) = 0;
-
- ///
- /// @brief receive a message.
- /// @return Error from operation
- /// @note fills our iv_key with the proper information
- ///
- virtual errlHndl_t recv(void) = 0;
-
- msg_t* iv_msg; // Pointer back to our msg_q msg_t
- uint8_t iv_key; // key used by the respond queue
-
- // Note: Some of these might turn out to be transport specific
- // if so, we'll just move them down in to the subclasses
- uint8_t iv_len; // Length
- uint8_t iv_netfun; // Network Function
- uint8_t& iv_seq; // Sequence number, reference to iv_key
- uint8_t iv_cmd; // Command
- uint8_t iv_cc; // Completion Code
- uint8_t iv_state; // Driver things, like EAGAIN
- errlHndl_t iv_errl; // Pointer to the errlHandl_t if needed
- uint8_t* iv_data; // Pointer to the message data
- timespec_t iv_timeout; // Absolute time of when I timeout
-
- private:
- // Disallow copying this class. Should suffice for disabling copy for
- // all subclasses too.
- Message& operator=(const Message&);
- Message(const Message&);
- };
-
-}; // end namespace IPMI
-
-#endif
diff --git a/src/usr/ipmi/ipmipowerstate.C b/src/usr/ipmi/ipmipowerstate.C
deleted file mode 100644
index 95d661a6e..000000000
--- a/src/usr/ipmi/ipmipowerstate.C
+++ /dev/null
@@ -1,86 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmipowerstate.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2015 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file ipmipowerstate.C
- *
- * Ipmi set ACPI Power State
- *
- */
-
-/******************************************************************************/
-// Includes
-/******************************************************************************/
-#include <stdint.h>
-#include <errl/errlentry.H>
-#include <ipmi/ipmipowerstate.H>
-#include <ipmi/ipmiif.H>
-
-/******************************************************************************/
-// Globals/Constants
-/******************************************************************************/
-// Defined in ipmidd.C
-extern trace_desc_t * g_trac_ipmi;
-#define IPMI_TRAC(printf_string,args...) \
- TRACFCOMP(g_trac_ipmi,"ps: " printf_string,##args)
-
-namespace IPMI
-{
-
-/******************************************************************************/
-// Functions
-/******************************************************************************/
-
-errlHndl_t setACPIPowerState()
-{
- errlHndl_t err_ipmi = NULL;
-
- size_t len = 2; // IPMI spec has request data at 2 bytes
-
- //create request data buffer
- uint8_t* data = new uint8_t[len];
-
- IPMI::completion_code cc = IPMI::CC_UNKBAD;
-
- data[0] = SET_SYSTEM_POWER_STATE | SET_LEGACY_ON;
- data[1] = NO_CHANGE_DEVICE_POWER;
-
- err_ipmi = IPMI::sendrecv(IPMI::set_acpi_power_state(), cc, len, data);
-
- //cleanup buffer
- delete[] data;
-
- if(cc != IPMI::CC_OK)
- {
- IPMI_TRAC("Set ACPI Power State: BMC returned not ok CC[%x]",cc);
- // should we log error and then retry?
- // what happens if the communication is broken
- // reset will try and set it again.
- }
-
- return err_ipmi;
-}
-
-} // namespace
-
diff --git a/src/usr/ipmi/ipmirp.C b/src/usr/ipmi/ipmirp.C
deleted file mode 100644
index 8afff0136..000000000
--- a/src/usr/ipmi/ipmirp.C
+++ /dev/null
@@ -1,1140 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmirp.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file ipmirp.C
- * @brief IPMI resource provider definition
- */
-
-#include "ipmirp.H"
-#include "ipmiconfig.H"
-#include "ipmidd.H"
-#include <ipmi/ipmi_reasoncodes.H>
-#include <ipmi/ipmiif.H>
-#include <ipmi/ipmisel.H>
-#include <devicefw/driverif.H>
-#include <devicefw/userif.H>
-
-#include <config.h>
-#include <sys/task.h>
-#include <initservice/taskargs.H>
-#include <initservice/initserviceif.H>
-#include <initservice/istepdispatcherif.H>
-#include <sys/vfs.h>
-
-#include <targeting/common/commontargeting.H>
-#include <kernel/ipc.H>
-#include <arch/ppc.H>
-#include <errl/errlmanager.H>
-#include <sys/time.h>
-#include <sys/misc.h>
-#include <errno.h>
-
-#include <console/consoleif.H>
-// Defined in ipmidd.C
-extern trace_desc_t * g_trac_ipmi;
-#define IPMI_TRAC(printf_string,args...) \
- TRACFCOMP(g_trac_ipmi,"rp: " printf_string,##args)
-
-/**
- * setup _start and handle barrier
- */
-TASK_ENTRY_MACRO( IpmiRP::daemonProcess );
-
-/**
- * @brief Constructor
- */
-IpmiRP::IpmiRP(void):
- iv_msgQ(msg_q_create()),
- iv_sendq(),
- iv_timeoutq(),
- iv_respondq(),
- iv_eventq(),
- iv_last_chanceq(msg_q_create()),
- iv_bmc_timeout(IPMI::g_bmc_timeout),
- iv_outstanding_req(IPMI::g_outstanding_req),
- iv_xmit_buffer_size(IPMI::g_xmit_buffer_size),
- iv_recv_buffer_size(IPMI::g_recv_buffer_size),
- iv_retries(IPMI::g_retries),
- iv_shutdown_msg(NULL),
- iv_graceful_shutdown_pending(false),
- iv_chassis_power_mod(IPMI::CHASSIS_POWER_OFF)
-{
- mutex_init(&iv_mutex);
- sync_cond_init(&iv_cv);
-}
-
-/**
- * @brief Destructor
- */
-IpmiRP::~IpmiRP(void)
-{
- msg_q_destroy(iv_msgQ);
-}
-
-void* IpmiRP::start(void* unused)
-{
- Singleton<IpmiRP>::instance().execute();
- return NULL;
-}
-
-void* IpmiRP::timeout_thread(void* unused)
-{
- Singleton<IpmiRP>::instance().timeoutThread();
- return NULL;
-}
-
-void* IpmiRP::get_capabilities(void* unused)
-{
- Singleton<IpmiRP>::instance().getInterfaceCapabilities();
- return NULL;
-}
-
-void* IpmiRP::last_chance_event_handler(void* unused)
-{
- Singleton<IpmiRP>::instance().lastChanceEventHandler();
- return NULL;
-}
-
-void IpmiRP::daemonProcess(errlHndl_t& o_errl)
-{
- task_create(&IpmiRP::attach, NULL);
- task_create(&IpmiRP::start, NULL);
-}
-
-/**
- * @brief Return the transport header size
- */
-size_t getXportHeaderSize(void)
-{
- // Get the header size from the physical transport.
- IPMI::Message* msg = IPMI::Message::factory();
- size_t xport_size = msg->header_size();
- delete msg;
- return xport_size;
-}
-
-/**
- * @brief Return the maximum data size to allocate
- */
-inline size_t IpmiRP::maxBuffer(void)
-{
- // If the interface isn't up (say we're sending the
- // get-capabilities command, or some such) we use the
- // defaults setup in the ctor.
-
- static size_t xport_header_size = getXportHeaderSize();
-
- mutex_lock(&iv_mutex);
-
- // Given the max buffer information from the get-capabilities
- // command, subtract off the physical layers header size.
-
- // iv_xmit_buffer_size can change - it'll be one thing for
- // the default when the RP is created, and possibly another
- // when the get-capabilities command returns.
- // an additional 1 is subtracted based on issues seen with AMI
- size_t mbs = iv_xmit_buffer_size - xport_header_size - 1;
-
- mutex_unlock(&iv_mutex);
-
- return mbs;
-}
-
-/**
- * @brief Start routine of the time-out handler
- */
-void IpmiRP::timeoutThread(void)
-{
- // Mark as an independent daemon so if it crashes we terminate.
- task_detach();
-
- IPMI_TRAC(ENTER_MRK "time out thread");
-
- // If there's something on the queue we want to grab it's timeout time
- // and wait. Note the response queue is "sorted" as we send messages in
- // order. So, the first message on the queue is the one who's timeout
- // is going to come first.
- while (true)
- {
- mutex_lock(&iv_mutex);
- while ((iv_timeoutq.size() == 0))
- {
- sync_cond_wait(&iv_cv, &iv_mutex);
- }
-
- msg_t*& msq_msg = iv_timeoutq.front();
- IPMI::Message* msg = static_cast<IPMI::Message*>(msq_msg->extra_data);
-
- // The difference between the timeout of the first message in the
- // queue and the current time is the time we wait for a timeout
- timespec_t tmp_time;
- clock_gettime(CLOCK_MONOTONIC, &tmp_time);
-
- uint64_t now = (NS_PER_SEC * tmp_time.tv_sec) + tmp_time.tv_nsec;
- uint64_t timeout = (NS_PER_SEC * msg->iv_timeout.tv_sec) +
- msg->iv_timeout.tv_nsec;
-
- if (now >= timeout)
- {
- IPMI_TRAC("timeout: %x:%x", msg->iv_netfun, msg->iv_cmd);
-
- // This little bugger timed out. Get him off the timeoutq
- iv_timeoutq.pop_front();
-
- // Get him off the responseq, and reply back to the waiter that
- // there was a timeout
- response(msg, IPMI::CC_TIMEOUT);
-
- // Tell the resource provider to check for any pending messages
- msg_t* msg_idleMsg = msg_allocate();
- msg_idleMsg->type = IPMI::MSG_STATE_IDLE;
- msg_send(iv_msgQ, msg_idleMsg);
-
- mutex_unlock(&iv_mutex);
- }
- else
- {
- mutex_unlock(&iv_mutex);
- nanosleep( 0, timeout - now );
- }
- }
- IPMI_TRAC(EXIT_MRK "time out thread");
-
- return;
-}
-
-/**
- * @brief Get the BMC interface capabilities
- */
-void IpmiRP::getInterfaceCapabilities(void)
-{
- // Mark as an independent daemon so if it crashes we terminate.
- task_detach();
-
- // Queue up a get-capabilities message. Anything that queues up behind us
- // (I guess it could queue up in front of us too ...) will use the defaults.
-
- IPMI::completion_code cc = IPMI::CC_UNKBAD;
- size_t len = 0;
- uint8_t* data = NULL;
- errlHndl_t err = IPMI::sendrecv(IPMI::get_capabilities(), cc, len, data);
-
- do {
- // If we have a problem, we can't "turn on" the IPMI stack.
- if (err)
- {
- IPMI_TRAC("get_capabilities returned an error, using defaults");
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
- break;
- }
-
- // If we get back a funky completion code, we'll use the defaults.
- if (cc != IPMI::CC_OK)
- {
- IPMI_TRAC("get_capabilities not ok %d, using defaults", cc);
- break;
- }
-
- // If we didn't get back what we expected, use the defaults
- if (len != 5)
- {
- IPMI_TRAC("get_capabilities length %d; using defaults", len);
- break;
- }
-
- // Protect the members as we're on another thread.
- mutex_lock(&iv_mutex);
- // @TODO RTC:123041 - In theory the number of outstanding requests is
- // set via the response data below, but currently the response
- // value isn't correct so the default will be used.
- //iv_outstanding_req = data[0];
- iv_xmit_buffer_size = data[1];
- iv_recv_buffer_size = data[2];
- // @TODO RTC:123041 - In theory the BMC timeout is set via the response
- // data below, but currently the response value isn't correct so
- // the default will be used.
- //iv_bmc_timeout = data[3];
- iv_retries = data[4];
-
- IPMI_TRAC("get_capabilities: requests %d, in buf %d, "
- "out buf %d, timeout %d, retries %d",
- iv_outstanding_req, iv_xmit_buffer_size,
- iv_recv_buffer_size, iv_bmc_timeout, iv_retries);
-
- mutex_unlock(&iv_mutex);
- } while(false);
-
- // store this size for hbrt's usage
- TARGETING::Target * sys = NULL;
- TARGETING::targetService().getTopLevelTarget( sys );
- if (sys)
- {
- sys->setAttr<TARGETING::ATTR_IPMI_MAX_BUFFER_SIZE>
- (iv_xmit_buffer_size - getXportHeaderSize() - 1);
- IPMI_TRAC("setAttr(IPMI_MAX_BUFFER_SIZE) = %d",
- (iv_xmit_buffer_size - getXportHeaderSize() - 1));
- }
-
- delete[] data;
-
- return;
-}
-
-/**
- * @brief Tell the resource provider which queue to use for events
- * @param[in] i_cmd, the command we're looking for
- * @param[in] i_msgq, the queue we should be notified on
- */
-void IpmiRP::registerForEvent(const IPMI::command_t& i_cmd,
- const msg_q_t& i_msgq)
-{
- mutex_lock(&iv_mutex);
-
- // We only need the command internally, but we create the entire
- // command_t as it's really the true representation of the event type.
- iv_eventq[i_cmd.second] = i_msgq;
- mutex_unlock(&iv_mutex);
- IPMI_TRAC("event registration for %x:%x", i_cmd.first, i_cmd.second);
-}
-
-void IPMI::register_for_event(const IPMI::command_t& i_cmd,
- const msg_q_t& i_msgq)
-{
- Singleton<IpmiRP>::instance().registerForEvent(i_cmd, i_msgq);
-}
-
-/**
- * @brief Give the resource provider a message to put in the eventq
- * @param[in] i_event, pointer to the new'd event (OEM SEL)
- */
-void IpmiRP::postEvent(IPMI::oemSEL* i_event)
-{
- // Called in the context of the RP message loop, mutex locked
-
- do {
- // Check to see if event is valid. AMI recomends we check the netfun,
- // the SEL id, and the record id. If they don't match, we're allowed
- // to consider this an unhandled message.
- if ( (i_event->iv_netfun != IPMI::OEM_VALID_NETFUN) ||
- (i_event->iv_record != IPMI::OEM_VALID_SEL_ID) ||
- (i_event->iv_record_type != IPMI::OEM_VALID_RECORD_TYPE) )
- {
- IPMI_TRAC("rejecting event netfun: 0x%x record: 0x%x record type: 0x%x cmd: 0x%x",
- i_event->iv_netfun,
- i_event->iv_record,
- i_event->iv_record_type,
- i_event->iv_cmd[0]);
-
- // ... and clean up the memory for the caller
- delete i_event;
- break;
- }
-
- // Check to see if this event has a queue registered
- IPMI::event_q_t::iterator it = iv_eventq.find(i_event->iv_cmd[0]);
- msg_q_t outq = (it == iv_eventq.end()) ? iv_last_chanceq : it->second;
-
- // Create a message to send asynchronously to the event handler queue
- // Assign the event to the message, the caller will delete the message
- // and the event.
- msg_t* msg = msg_allocate();
- msg->type = IPMI::TYPE_EVENT;
- msg->extra_data = i_event;
-
- IPMI_TRAC("queuing event %x:%x for handler",
- i_event->iv_netfun, i_event->iv_cmd[0])
- int rc = msg_send(outq, msg);
-
- if (rc)
- {
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISRV_POSTEVENT
- * @reasoncode IPMI::RC_INVALID_SEND
- * @userdata1 rc from msq_send()
- * @devdesc msg_send() failed
- * @custdesc Firmware error during IPMI event handling
- */
- errlHndl_t err =
- new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISRV_POSTEVENT,
- IPMI::RC_INVALID_SEND,
- rc,
- 0,
- true);
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
-
- // ... and clean up the memory for the caller
- delete i_event;
- msg_free(msg);
- }
-
- } while(0);
-
- return;
-}
-
-/**
- * @brief Send a message indicating we're rejecting the pnor handshake request.
- */
-static void rejectPnorRequest(void)
-{
- // Per AMI email, send a 0 to reject the pnor request.
- static const uint8_t reject_request = 0x0;
-
- uint8_t* data = new uint8_t(reject_request);
- IPMI_TRAC("rejecting pnor access request %x", *data);
-
- uint8_t len = 0;
- errlHndl_t err = send(IPMI::pnor_response(), len, data);
- if (err)
- {
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
- }
-}
-
-/**
- * @brief Handle various IPMI Power Messages
- */
-void IpmiRP::handlePowerMessage( IPMI::oemSEL* i_event )
-{
-
- do {
- // if the event type is "soft off" then update the modifier to send
- // a power off to the BMC
- if( i_event->iv_cmd[1] == IPMI::CHASSIS_POWER_OFF )
- {
- iv_chassis_power_mod = IPMI::CHASSIS_POWER_OFF;
-
- // handle the graceful shutdown message
- IPMI_TRAC("Graceful shutdown request received");
-
-#ifdef CONFIG_CONSOLE
- CONSOLE::displayf(NULL, "IPMI: shutdown requested");
- CONSOLE::flush();
-#endif
-
- }
- // If the event type is a power soft reset, send a chasis reset
- // update the modifier to send to the BMC
- else if( i_event->iv_cmd[1] == IPMI::CHASSIS_POWER_SOFT_RESET )
- {
- // handle the message as a power reset request
- IPMI_TRAC("IPMI power reset request received");
- iv_chassis_power_mod = IPMI::CHASSIS_POWER_RESET;
-#ifdef CONFIG_CONSOLE
- CONSOLE::displayf(NULL, "IPMI: power cycle requested");
- CONSOLE::flush();
-#endif
- }
- else
- {
- //Ignore this message - It is an undefined/unsupported command
- IPMI_TRAC("Ignoring command with unknown Power Control Action: %x",
- i_event->iv_cmd[1]);
- break;
- }
-
- // tell the istep dispacher to stop executing isteps
- INITSERVICE::stopIpl();
-
- // register for the post memory flush callback
- INITSERVICE::registerShutdownEvent(IPMI_COMP_ID, iv_msgQ,
- IPMI::MSG_STATE_GRACEFUL_SHUTDOWN,
- INITSERVICE::POST_MEM_FLUSH_NOTIFY_LAST);
-
- iv_graceful_shutdown_pending = true;
- lwsync();
-
- // initiate the shutdown processing in the background
- INITSERVICE::doShutdown(SHUTDOWN_STATUS_GOOD,true);
-
-
- } while (0);
-
-}
-/**
- * @brief Wait for events and read them
- */
-void IpmiRP::lastChanceEventHandler(void)
-{
- // Mark as an independent daemon so if it crashes we terminate.
- task_detach();
-
- // To create a event handler, all you need to do is create a message
- // queue (or use one you have) and register for events.
-
- // register with the resource provider, use the existing queue
- registerForEvent(IPMI::power_off(), iv_last_chanceq);
-
-
- // We'll handle the pnor request in this context as we just send
- // an async message which says "no."
- registerForEvent(IPMI::pnor_request(), iv_last_chanceq);
-
- do {
-
- msg_t* msg = msg_wait(iv_last_chanceq);
-
- IPMI::oemSEL* event = reinterpret_cast<IPMI::oemSEL*>(msg->extra_data);
-
- if (event->iv_cmd[0] == IPMI::pnor_request().second)
- {
- // We'll handle the pnor request in this context as we just send
- // an async message which says "no."
- rejectPnorRequest();
- }
- else if ( event->iv_cmd[0] == IPMI::power_off().second )
- {
- handlePowerMessage(event);
- }
- else {
- // TODO: RTC: 120128
- // The last-chance handler should do more than this - it needs to
- // respond back to the BMC and tell it whatever it needs to know. If
- // this response isn't simple for a specific message, then a real
- // handler should probably be written.
-
- IPMI_TRAC("last chance handler for event: %x:%x (%x %x %x)",
- event->iv_netfun, event->iv_cmd[0],
- event->iv_record, event->iv_record_type,
- event->iv_timestamp);
- }
- // There's no way anyone can post an event synchronously, so we're done.
- delete event;
- msg_free(msg);
-
- } while(true);
-
- return;
-}
-
-void* IpmiRP::attach(void *unused)
-{
- Singleton<IpmiRP>::instance().attach();
-
- return NULL;
-}
-
-void IpmiRP::attach(void)
-{
- task_detach();
-
- msg_q_t mq = Singleton<IpmiDD>::instance().eventQueue();
-
- /* FIXME: Never shut down */
- while (1)
- {
- /* Forward it into the internal message queue */
- msg_send(iv_msgQ, msg_wait(mq));
- lwsync();
- }
-}
-
-/**
- * @brief Entry point of the resource provider
- */
-void IpmiRP::execute(void)
-{
- bool l_shutdown_pending = false;
-
- // Mark as an independent daemon so if it crashes we terminate.
- task_detach();
-
- // Register shutdown events with init service.
- // Done at the "end" of shutdown processing.
- // This will flush out any IPMI messages which were sent as
- // part of the shutdown processing. We chose MBOX priority
- // as we don't want to accidentally get this message after
- // interrupt processing has stopped in case we need intr to
- // finish flushing the pipe.
- INITSERVICE::registerShutdownEvent(IPMI_COMP_ID, iv_msgQ,
- IPMI::MSG_STATE_SHUTDOWN,
- INITSERVICE::MBOX_PRIORITY);
-
- // Start the thread that waits for timeouts
- task_create( &IpmiRP::timeout_thread, NULL );
-
- // Queue and wait for a message for the interface capabilities
- task_create( &IpmiRP::get_capabilities, NULL);
-
- // Wait for an event message read it and handle it if no one else does
- task_create( &IpmiRP::last_chance_event_handler, NULL);
-
- // call ErrlManager function - tell him that IPMI is ready!
- ERRORLOG::ErrlManager::errlResourceReady(ERRORLOG::IPMI);
-
- while (true)
- {
-
- msg_t* msg = msg_wait(iv_msgQ);
-
- const IPMI::msg_type msg_type =
- static_cast<IPMI::msg_type>(msg->type);
-
- // Invert the "default" by checking here. This allows the compiler
- // to warn us if the enum has an un-handled case but still catch
- // runtime errors where msg_type is set out of bounds.
- assert(msg_type <= IPMI::MSG_LAST_TYPE,
- "msg_type %d not handled", msg_type);
-
- switch(msg_type)
- {
- // Messages we're told to send.
- // Push the message on the queue, and the idle() at the
- // bottom of this loop will start the transmit process.
- // Be sure to push_back to ensure ordering of transmission.
- case IPMI::MSG_STATE_SEND:
- if (!l_shutdown_pending)
- {
- iv_sendq.push_back(msg);
- }
- // shutting down, do not accept new messages
- else
- {
- IPMI_TRAC(WARN_MRK "IPMI shutdown pending. Message dropped");
- IPMI::Message* ipmi_msg =
- static_cast<IPMI::Message*>(msg->extra_data);
- response(ipmi_msg, IPMI::CC_BADSTATE);
- msg_free(msg);
- }
- break;
-
- // State changes from the IPMI hardware. These are async
- // messages so we get rid of them here.
- case IPMI::MSG_STATE_IDLE:
- msg_free(msg);
- // No-op - we do it at the bottom of the loop.
- break;
-
- // Handle a response (B2H_ATN)
- case IPMI::MSG_STATE_RESP:
- msg_free(msg);
- response();
- break;
-
- // Handle an event (SMS_ATN). The protocol states that when we see
- // the sms attention bit, we issue a read_event message, which will
- // come back with the OEM SEL of the event in its payload.
- case IPMI::MSG_STATE_EVNT:
- {
- msg_free(msg);
- uint8_t* data = NULL;
- uint8_t len = 0;
- errlHndl_t err = send(IPMI::read_event(), len, data,
- IPMI::TYPE_EVENT);
- if (err)
- {
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
- }
- }
- break;
-
- // Accept no more messages. Anything in the sendq is sent and
- // we wait for the reply from the BMC.
- case IPMI::MSG_STATE_SHUTDOWN:
- {
- l_shutdown_pending = true; // Stop incoming new messages
- iv_shutdown_msg = msg; // Reply to this message
- break;
- }
- case IPMI::MSG_STATE_GRACEFUL_SHUTDOWN:
- {
- IPMI_TRAC(INFO_MRK "MSG_STATE_GRACEFUL_SHUTDOWN: send power"
- " off command to BMC");
- // clear the graceful shutdown flag so we will exit after
- // sending the power off cmd
- iv_graceful_shutdown_pending = false;
- size_t len = 1;
- uint8_t* data = new uint8_t[len];
-
- // send the correct chassis power modifier.
- data[0] = iv_chassis_power_mod;
-
- IPMI::Message* ipmi_msg = IPMI::Message::factory(
- IPMI::chassis_power_off(), len, data, IPMI::TYPE_ASYNC);
-
- // queue up the power off message
- iv_sendq.push_back(ipmi_msg->iv_msg);
-
- iv_shutdown_msg = msg; // Reply to this message
-
-#ifdef CONFIG_CONSOLE
- CONSOLE::displayf(NULL, "IPMI: shutdown complete\n");
- CONSOLE::flush();
-#endif
-
- }
- break;
-
- // begin a graceful reboot initiated by us
- case IPMI::MSG_STATE_INITIATE_POWER_CYCLE:
- {
- msg_free(msg);
-
-#ifdef CONFIG_CONSOLE
- CONSOLE::displayf(NULL, "IPMI: Initiate power cycle");
- CONSOLE::flush();
-#endif
- // setup the power cmd modifier to tell the bmc to
- // do a power reset
- iv_chassis_power_mod = IPMI::CHASSIS_POWER_RESET;
-
- // register for the post memory flush callback
- INITSERVICE::registerShutdownEvent(IPMI_COMP_ID, iv_msgQ,
- IPMI::MSG_STATE_GRACEFUL_SHUTDOWN,
- INITSERVICE::POST_MEM_FLUSH_NOTIFY_LAST);
-
- iv_graceful_shutdown_pending = true;
- lwsync();
-
- // initiate the shutdown processing in the background
- INITSERVICE::doShutdown(SHUTDOWN_STATUS_GOOD,true);
-
- }
- break;
-
- };
-
- // There's a good chance the interface will be idle right after
- // the operation we just performed. Since we need to poll for the
- // idle state, calling idle after processing a message may decrease
- // the latency of waiting for idle. The worst case is that we find
- // the interface busy and go back to waiting. Note: there's no need
- // to keep calling idle if there are old elements on the sendq;
- // we'll need to wait for the interface to indicate we're idle.
- if ((IPMI::MSG_STATE_SEND != msg_type) || (iv_sendq.size() == 1))
- {
- idle();
- }
-
- // Once quiesced, reply to shutdown msg and exit.
- // Shutdown simply puts us in a state we deny all further requests bar
- // those from PnorIpmiDD. Access to the PNOR must be provided right up
- // until we call the shutdown syscall, so there's no point at which we
- // can deallocate the resources consumed by IpmiRP, IpmiDD or
- // PnorIpmiDD.
- if (l_shutdown_pending && iv_respondq.empty() && iv_sendq.empty())
- {
- IPMI_TRAC(INFO_MRK "reply to the MSG_STATE_SHUTDOWN message");
- msg_respond(iv_msgQ, iv_shutdown_msg);
- }
- }
-
- IPMI_TRAC(EXIT_MRK "message loop");
- return;
-}
-
-///
-/// @brief Go in to the idle state
-///
-void IpmiRP::idle(void)
-{
- // If the interface is idle, we can write anything we need to write.
- for (IPMI::send_q_t::iterator i = iv_sendq.begin();
- i != iv_sendq.end();)
- {
- // Check to see if we have many outstanding requests. If so, don't send
- // any more messages. Note the eagain mechanism still works even though
- // we're not sending messages as eventually we'll get enough responses
- // to shorten the response queue and since the message loop calls us
- // to transmit even for the reception of a message, the driver will
- // eventually reset egagains. If responses timeout, we end up here as
- // the response queue processing sends an idle message when anything is
- // removed.
- if (iv_outstanding_req <= iv_respondq.size())
- {
- break;
- }
-
- // If we have a problem transmitting a message, then we just stop
- // here and wait for the next time the interface transitions to idle
- // Note that there are two failure cases: the first is that there is
- // a problem transmitting. In this case we told the other end of the
- // message queue, and so the life of this message is over. The other
- // case is that the interface turned out to be busy in which case
- // this message can sit on the queue and it'll be next.
-
- IPMI::Message* msg = static_cast<IPMI::Message*>((*i)->extra_data);
-
- // If there was an i/o error, we do nothing - leave this message on
- // the queue. Don't touch msg after xmit returns. If the message was
- // sent, and it was async, msg has been destroyed.
- if (msg->xmit())
- {
- break;
- }
- i = iv_sendq.erase(i);
- }
-
- return;
-}
-
-///
-/// @brief Handle a response to a message we sent
-///
-void IpmiRP::response(void)
-{
- IPMI::Message* rcv_buf = IPMI::Message::factory();
-
- do
- {
- // Go down to the device and read. Fills in iv_key.
- errlHndl_t err = rcv_buf->recv();
-
- if (err)
- {
- // Not much we're going to do here, so lets commit the error and
- // the original request will timeout.
- err->collectTrace(IPMI_COMP_NAME);
- errlCommit(err, IPMI_COMP_ID);
- break;
- }
-
- mutex_lock(&iv_mutex);
- response(rcv_buf);
- mutex_unlock(&iv_mutex);
-
- } while (false);
-
- delete rcv_buf;
- return;
-}
-
-///
-/// @brief Handle a response to a message we want to change
-///
-void IpmiRP::response(IPMI::Message* i_msg, IPMI::completion_code i_cc)
-{
- // The third bit in the netfun indicates this is a reply.
- static const uint8_t reply_bit = 0x04;
-
- i_msg->iv_cc = i_cc;
- i_msg->iv_netfun |= reply_bit; // update the netfun
- i_msg->iv_len = 0; // sending no data
- i_msg->iv_data = NULL;
- response(i_msg);
- return;
-}
-
-///
-/// @brief Handle a response to a message we have
-///
-void IpmiRP::response(IPMI::Message* i_msg)
-{
- do {
-
- // Look for a message with this seq number waiting for a
- // response. If there isn't a message looking for this response,
- // log and leave. Async messages should also be on this queue,
- // even though the caller has long gone on to other things.
- IPMI::respond_q_t::iterator itr = iv_respondq.find(i_msg->iv_key);
- if (itr == iv_respondq.end())
- {
- IPMI_TRAC(ERR_MRK "message not found on the response queue: "
- "%d %x:%x", i_msg->iv_key, i_msg->iv_netfun,
- i_msg->iv_cmd);
-
- delete[] i_msg->iv_data;
- break;
- }
-
- msg_t* original_msg = itr->second;
-
- // Get us off the response queue, and the timeout queue.
- iv_respondq.erase(itr);
- iv_timeoutq.remove(original_msg);
-
- // Hand the allocated buffer over to the original message's
- // ipmi_msg_t It will be responsible for de-allocating it
- // when it's dtor is called.
- IPMI::Message* ipmi_msg =
- static_cast<IPMI::Message*>(original_msg->extra_data);
-
- // Hand ownership of the data to the original requester
- ipmi_msg->iv_data = i_msg->iv_data;
- ipmi_msg->iv_len = i_msg->iv_len;
- ipmi_msg->iv_cc = i_msg->iv_cc;
- ipmi_msg->iv_netfun = i_msg->iv_netfun;
-
- // The subclasses know how to handle the response from here.
- // For example, sync messages will respond and async will delete
- ipmi_msg->response(iv_msgQ);
-
- } while(false);
-
- return;
-}
-
-///
-/// @brief Queue a message on to the response queue
-///
-void IpmiRP::queueForResponse(IPMI::Message& i_msg)
-{
- // Figure out when this fellow's timeout should occur. If we
- // have a problem from clock_gettime we have a bug, not an error.
- clock_gettime(CLOCK_MONOTONIC, &(i_msg.iv_timeout));
-
- // Lock before accessing the timeout (and the queues, etc.)
- mutex_lock(&iv_mutex);
-
- // BMC request-to-response times are always seconds, 1 - 30.
- // And I don't think we care about roll over here.
- i_msg.iv_timeout.tv_sec += iv_bmc_timeout;
-
- // Put this message on the response queue so we can find it later
- // for a response and on the timeout queue so if it times out
- // we can find it there. Note all message will all have the same
- // timeout - mostly. Every message sent before the BMC tells us
- // the timeout (at least one message) will have the shortest possible
- // timeout. The BMC might lengthen the timeout, but can not shorten
- // it. All messages after that will have the same timeout. So the
- // timeout queue is "sorted."
-
- iv_respondq[i_msg.iv_seq] = i_msg.iv_msg;
- iv_timeoutq.push_back(i_msg.iv_msg);
-
- // If we put a message in an empty timeout queue (we know this as
- // there's only one message in the queue now) signal the timeout thread
- if (iv_timeoutq.size() == 1)
- {
- sync_cond_signal(&iv_cv);
- }
-
- mutex_unlock(&iv_mutex);
- return;
-}
-
-namespace IPMI
-{
- ///
- /// @brief Synchronus message send
- ///
- errlHndl_t sendrecv(const IPMI::command_t& i_cmd,
- IPMI::completion_code& o_completion_code,
- size_t& io_len, uint8_t*& io_data)
- {
- errlHndl_t err;
- static msg_q_t mq = Singleton<IpmiRP>::instance().msgQueue();
-
- IPMI::Message* ipmi_msg = IPMI::Message::factory(i_cmd, io_len, io_data,
- IPMI::TYPE_SYNC);
-
- // I think if the buffer is too large this is a programming error.
- assert(io_len <= max_buffer());
-
- IPMI_TRAC("queuing sync %x:%x", ipmi_msg->iv_netfun, ipmi_msg->iv_cmd);
- int rc = msg_sendrecv(mq, ipmi_msg->iv_msg);
-
- // If the kernel didn't give a hassle about the message, check to see if
- // there was an error reported back from the other end of the queue. If
- // this message made it to the other end of the queue, then our memory
- // (io_data) is in the proper state.
- if (rc == 0) {
- err = ipmi_msg->iv_errl;
- }
-
- // Otherwise, lets make an errl out of our return code
- else
- {
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISRV_SEND
- * @reasoncode IPMI::RC_INVALID_SENDRECV
- * @userdata1 rc from msq_sendrecv()
- * @devdesc msg_sendrecv() failed
- * @custdesc Firmware error during system boot
- */
- err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISRV_SEND,
- IPMI::RC_INVALID_SENDRECV,
- rc,
- 0,
- true);
- err->collectTrace(IPMI_COMP_NAME);
-
- // ... and clean up the memory for the caller
- delete[] io_data;
- }
-
- // The length and the data are the response, if there was one. All of
- // there are pretty much invalid if there was an error.
- io_len = ipmi_msg->iv_len;
- io_data = ipmi_msg->iv_data;
- o_completion_code = static_cast<IPMI::completion_code>(ipmi_msg->iv_cc);
- delete ipmi_msg;
-
- return err;
- }
-
- ///
- /// @brief Asynchronous message send
- ///
- errlHndl_t send(const IPMI::command_t& i_cmd,
- const size_t i_len, uint8_t* i_data,
- IPMI::message_type i_type)
- {
- static msg_q_t mq = Singleton<IpmiRP>::instance().msgQueue();
- errlHndl_t err = NULL;
-
- // We don't delete this message, the message will self destruct
- // after it's been transmitted. Note it could be placed on the send
- // queue and we are none the wiser - so we can't delete it.
- IPMI::Message* ipmi_msg = IPMI::Message::factory(i_cmd, i_len,
- i_data, i_type);
-
- // I think if the buffer is too large this is a programming error.
- assert(i_len <= max_buffer());
-
- IPMI_TRAC("queuing async %x:%x", ipmi_msg->iv_netfun, ipmi_msg->iv_cmd);
- int rc = msg_send(mq, ipmi_msg->iv_msg);
-
- if (rc)
- {
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISRV_SEND
- * @reasoncode IPMI::RC_INVALID_SEND
- * @userdata1 rc from msq_send()
- * @devdesc msg_send() failed
- * @custdesc Firmware error during system boot
- */
- err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISRV_SEND,
- IPMI::RC_INVALID_SEND,
- rc,
- 0,
- true);
- err->collectTrace(IPMI_COMP_NAME);
-
- // ... and clean up the memory for the caller
- delete[] i_data;
- }
-
- return err;
- }
-
- void initiateShutdownOrReboot(const IPMI::msg_type i_msgType)
- {
- const auto valid = IPMI::validShutdownRebootMsgType(i_msgType);
- assert(valid,"BUG! IPMI message type of 0x%08X is not a valid shutdown "
- "or reboot type",i_msgType);
- static auto mq = Singleton<IpmiRP>::instance().msgQueue();
- auto pMsg = msg_allocate();
- assert(pMsg != nullptr,"BUG! msg_allocate returned nullptr.");
- pMsg->type = i_msgType;
- auto rc = msg_send(mq,pMsg);
- assert(!rc,"BUG! msg_send failed with rc of %d",rc);
- }
-
- void initiateReboot()
- {
- (void)initiateShutdownOrReboot(MSG_STATE_INITIATE_POWER_CYCLE);
- }
-
- void initiatePowerOff()
- {
- (void)initiateShutdownOrReboot(MSG_STATE_GRACEFUL_SHUTDOWN);
- }
-
- ///
- /// @brief Maximum buffer for data (max xport - header)
- ///
- size_t max_buffer(void)
- {
- return Singleton<IpmiRP>::instance().maxBuffer();
- }
-
- ///
- /// @brief Synchronously send an event
- ///
- errlHndl_t send_event(const uint8_t i_sensor_type,
- const uint8_t i_sensor_number,
- const bool i_assertion,
- const uint8_t i_type,
- completion_code& o_completion_code,
- const size_t i_len,
- uint8_t* i_data)
- {
- static const size_t event_header = 5;
-
- // Sanity check
- assert((i_len > 0) && (i_len < 4),
- "event request i_len incorrect %d", i_len);
- assert(i_type < 0x80, "event request i_type out of range %x", i_type);
-
- size_t len = event_header + i_len;
- uint8_t* data = new uint8_t[len];
- IPMI::completion_code cc = IPMI::CC_OK;
-
- data[0] = 0x01; // More or less fixed, see table 5.4
- data[1] = 0x04; // Fixed in the IPMI spec table 29.5
- data[2] = i_sensor_type;
- data[3] = i_sensor_number;
- data[4] = (i_assertion ? 0x80 : 0x00) + i_type;
- for (size_t i = 0; i < i_len; i++)
- {
- data[event_header + i] = i_data[i];
- }
-
- // We're done with i_data, but the caller deletes it. Note there's
- // no response data to an event - so there's nothing to copy over,
- // no reference to i_data, nothing.
-
- errlHndl_t err = sendrecv(IPMI::platform_event(), cc, len, data);
-
- o_completion_code = cc;
- delete[] data;
- return err;
- }
-
- /**
- * Retrieve some information about the BMC and the connection
- * we have to it.
- */
- BmcInfo_t getBmcInfo(void)
- {
- BmcInfo_t l_info;
-
- l_info.bulkTransferLpcBaseAddr = REG_HOSTBMC;
- static size_t size = sizeof(uint8_t);
- l_info.bulkTransferSize = size;
- l_info.chipVersion = cpu_dd_level();
- l_info.smsAttnInterrupt = CTRL_SMS_ATN;
- l_info.bmcToHostInterrupt = CTRL_B2H_ATN;
-
- //TODO RTC:162537 Add in non-generic bmc vendors AMI, Aten and OpenBmc
- char l_vendor[32] = "openpower,generic";
- strncpy(l_info.bmcVendor,l_vendor,sizeof(l_info.bmcVendor));
-
-
- return l_info;
- }
-
-}; // End namespace IPMI
diff --git a/src/usr/ipmi/ipmirp.H b/src/usr/ipmi/ipmirp.H
deleted file mode 100644
index 0f9b02302..000000000
--- a/src/usr/ipmi/ipmirp.H
+++ /dev/null
@@ -1,284 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmirp.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-#ifndef __IPMI_IPMIRP_H
-#define __IPMI_IMPIRP_H
-
-/**
- * @file ipmirp.H
- * @brief IPMI service provider declariation
- */
-
-#include <stdint.h>
-#include <builtins.h>
-#include <ipmi/ipmiif.H>
-#include <errl/errlentry.H>
-#include <sys/msg.h>
-#include <sys/sync.h>
-#include <list>
-#include <map>
-#include <util/locked/list.H>
-#include <intr/interrupt.H>
-#include <limits.h>
-
-#include "ipmimsg.H"
-
-namespace TARGETING
-{
- class Target;
-};
-
-class IpmiRP
-{
- public:
-
- /**
- * Initialize the IPMI service
- * @param[in] o_errl, NULL if OK
- */
- static void daemonProcess(errlHndl_t& o_errl);
-
- /**
- * IpmiDD data source
- */
- static void* attach(void *unused);
-
- /**
- * Thread start routine for the resource provider
- * @param[in] void*, unused
- */
- static void* start(void* unused);
-
- /**
- * Thread start routine for the timeout thread
- * @param[in] void*, unused
- */
- static void* timeout_thread(void* unused);
-
- /**
- * Thread start routine for a little task which
- * waits for the BMC to give us the interface capabilties
- * @param[in] void*, unused
- */
- static void* get_capabilities(void* unused);
-
- /**
- * Thread start routine for a little task which handles events
- * which aren't registered by any other task
- * @param[in] void*, unused
- */
- static void* last_chance_event_handler(void* unused);
-
- /**
- * Default constructor
- */
- IpmiRP(void);
-
- /**
- * Destructor
- */
- ~IpmiRP(void);
-
- /**
- * The mailbox service provider task
- */
- void msgHandler(void);
-
- /**
- * Return the max data buffer to allocate for the underlying transport.
- */
- inline size_t maxBuffer(void);
-
- /**
- * @brief Get the message queue associated with this RP
- * @param[in] void
- * @return, a msg_q_t which is the message queue
- */
- msg_q_t msgQueue(void)
- { return iv_msgQ; }
-
- /**
- * @brief Queue a message on to the response queue
- * @param[in] i_msg, the message to queue
- */
- void queueForResponse(IPMI::Message& i_msg);
-
- /**
- * @brief Tell the resource provider which queue to use for events
- * @param[in] i_cmd, the command we're looking for
- * @param[in] i_msgq, the queue we should be notified on
- */
- void registerForEvent(const IPMI::command_t& i_cmd, const msg_q_t& i_msgq);
-
- /**
- * @brief Give the resource provider a message to put in the eventq
- * @param[in] i_event, pointer to the new'd event (OEM SEL)
- */
- void postEvent(IPMI::oemSEL* i_event);
-
- /**
- * @brief Give the resource provider a message to put in the eventq
- * @param[in] i_event, pointer to the power event data to handle (OEM SEL)
- */
- void handlePowerMessage(IPMI::oemSEL* i_event);
-
- private:
- void attach(void);
-
- /**
- * Entry point for the resource provider
- */
- void execute(void);
-
- /**
- * Entry point for the timeout thread
- */
- void timeoutThread(void);
-
- /**
- * @brief Transmit a message over the IPMI interface
- * @param[in] i_msg, ptr to the message_q message
- * @note i_msg is not const because it contains a return code
- */
- int xmit(msg_t* i_msg);
-
- /**
- * @brief Transmit a synchronous message over the IPMI interface
- * @param[in] i_msg, ptr to the message_q message
- * @note this is a message used internally to send a message
- * over the IPMI interface and wait for a response from the BMC
- * @note i_msg is not const because it contains a return code
- */
- void xmit_sync(msg_t* i_msg);
-
- /**
- * @brief Transmit an asynchronous message over the IPMI interface
- * @param[in] i_msg, ptr to the message_q message
- * @note this is a message used internally to send a message
- * over the IPMI interface and not wait for a response from the BMC
- * @note i_msg is not const because it contains a return code
- */
- void xmit_async(msg_t* i_msg);
-
- /**
- * @brief Handle a message from the interface indicating the
- * interface has gone idle (and can be written to.)
- * @param[in] void
- */
- void idle(void);
-
- /**
- * @brief Handle an indication from the interface indicating the
- * BMC interface has a response message ready to read
- * @param[in] void
- */
- void response(void);
-
- /**
- * @brief Respond to an existing message.
- * @note This is used as the "base" response handler
- * @param[in] i_msg, the message to respond to
- */
- void response(IPMI::Message* i_msg);
-
- /**
- * @brief Respond to a message we're changing
- * @note This is used when we have a timeout and need to
- * respond to the caller.
- * @param[in] i_msg, the message to respond to
- * @param[in] i_cc, the complettion code
- */
- void response(IPMI::Message* i_msg, IPMI::completion_code i_cc);
-
- /**
- * @brief Query the BMC for interface capabilities
- * @param[in] void
- * @note this fills in iv_bmc_timeout, etc.
- */
- void getInterfaceCapabilities(void);
-
- /**
- * @brief Process incoming event messages if they're not processed by
- * any other task.
- * @param[in] void
- */
- void lastChanceEventHandler(void);
-
- msg_q_t iv_msgQ; //!< ipmi mesage queue
- IPMI::send_q_t iv_sendq; //!< msg to send queue
- IPMI::timeout_q_t iv_timeoutq; //!< msgs waiting for a timeout
- IPMI::respond_q_t iv_respondq; //!< msg respond pending list
- IPMI::event_q_t iv_eventq; //!< map events to msg_t
- msg_q_t iv_last_chanceq; //!< last chance event queue
-
- // Protect the queues from the message loop and the timeout thread
- mutex_t iv_mutex;
- sync_cond_t iv_cv;
-
- // The time, in seconds, the BMC told us is the max request/response
- // time interval.
- uint8_t iv_bmc_timeout;
-
- // How many outstanding requests the BMC can handle
- uint8_t iv_outstanding_req;
-
- // Size of the xmit buffer (max we can send)
- uint8_t iv_xmit_buffer_size;
-
- // Size of the recv buffer (max BMC will send)
- uint8_t iv_recv_buffer_size;
-
- // Recommended number of retries
- uint8_t iv_retries;
-
- // Shutdown
- msg_t * iv_shutdown_msg; //!< shutdown msg to respond to
-
- //!< handle ipmi chassis power off request
- bool iv_graceful_shutdown_pending;
-
- //!< handle ipmi chassis power off request modifier
- IPMI::power_request_type iv_chassis_power_mod;
-
- // Disallow copying this class.
- IpmiRP& operator=(const IpmiRP&);
- IpmiRP(const IpmiRP&);
-};
-
-namespace IPMI
-{
- /**
- * @brief Initiate generic IPMI shutdown/reboot request via the IPMI
- * resource provider
- *
- * @param[in] i_msgType IPMI message type indicating the shutdown or reboot
- * to request. Asserts if not a valid shutdown or reboot message type as
- * determined by IPMI::validShutdownRebootMsgType().
- */
- void initiateShutdownOrReboot(IPMI::msg_type i_msgType);
-
-} // End IPMI namespace
-
-#endif
diff --git a/src/usr/ipmi/ipmisel.C b/src/usr/ipmi/ipmisel.C
deleted file mode 100644
index 6b7618fd9..000000000
--- a/src/usr/ipmi/ipmisel.C
+++ /dev/null
@@ -1,596 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmisel.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
-/* [+] Google Inc. */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file ipmisel.C
- * @brief IPMI system error log transport definition
- */
-
-#include <algorithm>
-#include <sys/time.h>
-#include <ipmi/ipmisel.H>
-#include <ipmi/ipmi_reasoncodes.H>
-#include <ipmi/ipmisensor.H>
-#include <ipmi/ipmiif.H>
-
-#include <sys/task.h>
-#include <initservice/taskargs.H>
-#include <initservice/initserviceif.H>
-#include <targeting/common/commontargeting.H>
-#include <targeting/common/util.H>
-#include <targeting/common/utilFilter.H>
-
-#include <errl/errlmanager.H>
-using namespace TARGETING;
-
-//Defined in ipmidd.C
-extern trace_desc_t * g_trac_ipmi;
-#define IPMI_TRAC(printf_string,args...) \
- TRACFCOMP(g_trac_ipmi,"sel: " printf_string,##args)
-
-// local functions
-/*
- * @brief Store either Record/Reserve ID from given data
- */
-void storeReserveRecord(uint8_t* o_RData, uint8_t* i_data)
-{
- o_RData[0] = i_data[0];
- o_RData[1] = i_data[1];
- return;
-}
-
-/*
- * @brief Create Partial Add eSEL Header from inputs
- */
-void createPartialAddHeader(uint8_t* i_reserveID, uint8_t* i_recordID,
- uint16_t i_offset, uint8_t i_isLastEntry,
- uint8_t* o_header)
-{
- o_header[0] = i_reserveID[0];
- o_header[1] = i_reserveID[1];
- o_header[2] = i_recordID[0];
- o_header[3] = i_recordID[1];
- o_header[4] = (uint8_t)(i_offset & 0x00FF);
- o_header[5] = (uint8_t)((i_offset & 0xFF00) >> 8);
- o_header[6] = i_isLastEntry;
- return;
-}
-
-enum esel_retry
-{
- MAX_SEND_COUNT = 4,
- SLEEP_BASE = 2 * NS_PER_MSEC,
-};
-
-
-namespace IPMISEL
-{
-void sendESEL(uint8_t* i_eselData, uint32_t i_dataSize,
- uint32_t i_eid, std::vector<sel_info_t*>&i_selEventList,
- bool i_infoCallHome)
-{
- IPMI_TRAC(ENTER_MRK "sendESEL() %d",i_selEventList.size());
-
-#ifdef __HOSTBOOT_RUNTIME
- // HBRT doesn't send a msg, but use the msg structure to pass the data
- msg_t l_msg;
- msg_t *msg = &l_msg;
- memset(msg, 0, sizeof(msg_t));
-#else
- msg_t *msg = msg_allocate();
-#endif
- msg->type = MSG_SEND_ESEL;
- auto * const pData = reinterpret_cast<send_esel_data_t*>
- (msg->data);
- pData->callhome=i_infoCallHome;
- pData->eid=i_eid;
-
- eselInitData *eselData =
- new eselInitData(i_selEventList, i_eselData, i_dataSize);
-
- msg->extra_data = eselData;
-
-#ifdef __HOSTBOOT_RUNTIME
- process_esel(msg);
-#else
- // one message queue to the SEL thread
- static msg_q_t mq = Singleton<IpmiSEL>::instance().msgQueue();
-
- //Send the msg to the sel thread
- int rc = msg_send(mq,msg);
- if(rc)
- {
- IPMI_TRAC(ERR_MRK "Failed (rc=%d) to send message",rc);
- delete eselData;
- }
-#endif
- IPMI_TRAC(EXIT_MRK "sendESEL");
- return;
-}
-
-/*
- * @brief process esel msg
- */
-void process_esel(msg_t *i_msg)
-{
- errlHndl_t l_err = NULL;
- IPMI::completion_code l_cc = IPMI::CC_UNKBAD;
-
- assert(i_msg != nullptr,"i_msg was nullptr");
- const auto * const pData = reinterpret_cast<const send_esel_data_t*>
- (i_msg->data);
- const auto callhome = pData->callhome;
- const auto l_eid = pData->eid;
-
- eselInitData * l_data =
- (eselInitData*)(i_msg->extra_data);
- IPMI_TRAC(ENTER_MRK "process_esel");
- selRecord l_eSel;
- oemSelRecord l_oemSel;
-
- do
- {
- IPMI_TRAC(ENTER_MRK"sel list size %d", l_data->selInfoList.size());
- std::vector<sel_info_t*>::iterator it;
- for (it = l_data->selInfoList.begin(); it != l_data->selInfoList.end();
- ++it)
- {
- sel_info_t *l_sel = *it;
- memset(l_data->oemSel,0,sizeof(oemSelRecord));
- memset(l_data->eSel,0,sizeof(selRecord));
- l_data->selEvent = true;
-
- //If sensor type is sys event then need to send the oem sel
- //to handle procedure callout
- if (l_sel->sensorType == TARGETING::SENSOR_TYPE_SYS_EVENT)
- {
- //oem sel data
- l_data->selEvent = false;
- l_oemSel.record_type =
- record_type_oem_sel_for_procedure_callout;
- l_oemSel.event_data1 = l_sel->eventOffset;
- l_sel->eventOffset = SENSOR::UNDETERMINED_SYSTEM_HW_FAILURE;
- memcpy(l_data->oemSel,&l_oemSel,sizeof(oemSelRecord));
- }
-
- //sel data
- l_eSel.record_type = record_type_system_event;
- l_eSel.generator_id = generator_id_ami;
- l_eSel.evm_format_version = format_ipmi_version_2_0;
- l_eSel.sensor_type = l_sel->sensorType;
- l_eSel.sensor_number = l_sel->sensorNumber;
- l_eSel.event_dir_type = l_sel->eventDirType;
- l_eSel.event_data1 = l_sel->eventOffset;
- memcpy(l_data->eSel,&l_eSel,sizeof(selRecord));
-
-
- uint32_t l_send_count = MAX_SEND_COUNT;
- while (l_send_count > 0)
- {
- // try to send the esel to the bmc
- send_esel(l_data, l_err, l_cc, callhome);
-
- // if no error but last completion code was:
- if ((l_err == NULL) &&
- ((l_cc == IPMI::CC_BADRESV) || // lost reservation
- (l_cc == IPMI::CC_TIMEOUT))) // timeout
- {
- // update our count and pause
- l_send_count--;
- if (l_send_count)
- {
- IPMI_TRAC("process_esel: sleeping; retry_count %d",
- l_send_count);
- // sleep 3 times - 2ms, 32ms, 512ms. if we can't get this
- // through by then, the system must really be busy...
- nanosleep(0,
- SLEEP_BASE << (4 * (MAX_SEND_COUNT - l_send_count - 1)));
- continue;
- }
- }
- else
- {
- //if we enter this, then pel data has logged successfully,
- //so we don't need to log again, make the size to zero.
- l_data->dataSize = 0;
- }
- // else it did get sent down OR it didn't because of a bad error
- break;
- } // while
- } // for
-
- }while(0);
-
- if(l_err)
- {
-#ifdef __HOSTBOOT_RUNTIME
- // HBRT can't commit an error, since this could already be in the
- // errlCommit path since HBRT is single threaded
- IPMI_TRAC(ERR_MRK "DELETING l_err 0x%.8X", l_err->eid());
- delete l_err;
- l_err = NULL;
-#else
- l_err->collectTrace(IPMI_COMP_NAME);
- errlCommit(l_err, IPMI_COMP_ID);
-#endif
- }
- else if((l_cc == IPMI::CC_OK) && // no error
- (l_eid != 0)) // and it's an errorlog
- {
- // eSEL successfully sent to the BMC - have errlmanager do the ack
- IPMI_TRAC(INFO_MRK "Doing ack for eid 0x%.8X", l_eid);
- ERRORLOG::ErrlManager::errlAckErrorlog(l_eid);
- }
-
- delete l_data;
-
- IPMI_TRAC(EXIT_MRK "process_esel");
- return;
-} // process_esel
-
-/*
- * @brief Send esel data to bmc
- */
-void send_esel(eselInitData * i_data,
- errlHndl_t &o_err, IPMI::completion_code &o_cc,
- bool i_infoCallHome)
-{
- IPMI_TRAC(ENTER_MRK "send_esel");
- uint8_t* data = NULL;
-
- size_t len = 0;
-
- uint8_t sel_recordID[2] = {0,0};
- uint8_t esel_recordID[2] = {0,0};
-
- do
- {
- const size_t l_eSELlen = i_data->dataSize;
-
- if (l_eSELlen == 0)
- {
- IPMI_TRAC(INFO_MRK "no eSEL data present, skipping to SEL");
-
- // sending sensor SELs only, not the eSEL
- o_cc = IPMI::CC_OK;
-
- break;
- }
-
- uint8_t reserveID[2] = {0,0};
- // we need to send down the extended sel data (eSEL), which is
- // longer than the protocol buffer, so we need to do a reservation and
- // call the AMI partial_add_esel command multiple times
-
- // put a reservation on the SEL Device since we're doing a partial_add
- len = 0;
- delete [] data;
- data = NULL;
- o_cc = IPMI::CC_UNKBAD;
- o_err = IPMI::sendrecv(IPMI::reserve_sel(),o_cc,len,data);
- if(o_err)
- {
- IPMI_TRAC(ERR_MRK "error from reserve_sel");
- break;
- }
- if(o_cc != IPMI::CC_OK)
- {
- IPMI_TRAC(ERR_MRK "Failed to reserve_sel, o_cc %02x",o_cc);
- break;
- }
- storeReserveRecord(reserveID,data);
-
- // first send down the SEL Event Record data
- size_t eSELindex = 0;
- uint8_t l_lastEntry = 0;
- len = PARTIAL_ADD_ESEL_REQ + sizeof(selRecord);
- delete [] data;
- data = new uint8_t[len];
-
- // fill in the partial_add_esel request (command) data
- createPartialAddHeader(reserveID,esel_recordID,eSELindex,l_lastEntry,data);
-
- // copy in the SEL event record data
- memcpy(&data[PARTIAL_ADD_ESEL_REQ], i_data->eSel,
- sizeof(selRecord));
-
- // add record type for this eSEL
- if (i_infoCallHome)
- {
- data[PARTIAL_ADD_ESEL_REQ + offsetof(selRecord,record_type)] =
- record_type_oem_call_home_info_event;
- }
- else
- {
- data[PARTIAL_ADD_ESEL_REQ + offsetof(selRecord,record_type)] =
- record_type_ami_esel;
- }
-
- data[PARTIAL_ADD_ESEL_REQ + offsetof(selRecord,event_data1)] =
- event_data1_ami;
-
- o_cc = IPMI::CC_UNKBAD;
- TRACFBIN( g_trac_ipmi, INFO_MRK"1st partial_add_esel:", data, len);
- o_err = IPMI::sendrecv(IPMI::partial_add_esel(),o_cc,len,data);
- if(o_err)
- {
- IPMI_TRAC(ERR_MRK "error from first partial_add_esel");
- break;
- }
- // as long as we continue to get CC_OK, the reserve sel is good.
- // if the reservation is lost (ie, because something else tried to
- // create a SEL) then the BMC just discards all this data. the
- // errorlog will still be in PNOR and won't get ACKed, so it'll get
- // resent on the next IPL.
- if (o_cc != IPMI::CC_OK)
- {
- IPMI_TRAC(ERR_MRK "failed first partial_add_esel, o_cc %02x, eSELindex %02x",
- o_cc, eSELindex);
- break;
- }
- // BMC returns the recordID, it's always the same (unless
- // there's a major BMC bug...)
- storeReserveRecord(esel_recordID,data);
-
- // now send down the eSEL data in chunks.
- const size_t l_maxBuffer = IPMI::max_buffer();
- while(eSELindex<l_eSELlen)
- {
- //if the index + the maximum buffer is less than what we still
- //have left in the eSEL, this is not the last entry (data[6] = 0)
- //otherwise, it is and data[6] = 1
- if(eSELindex + (l_maxBuffer - PARTIAL_ADD_ESEL_REQ)
- < l_eSELlen)
- {
- len = l_maxBuffer;
- l_lastEntry = 0x00;
- }
- else
- {
- len = l_eSELlen - eSELindex + PARTIAL_ADD_ESEL_REQ;
- l_lastEntry = 0x01;
- }
- delete [] data;
- data = new uint8_t[len];
-
- // fill in the partial_add_esel request (command) data
- createPartialAddHeader(reserveID, esel_recordID,
- eSELindex + sizeof(selRecord),
- l_lastEntry, data);
-
- uint8_t dataCpyLen = len - PARTIAL_ADD_ESEL_REQ;
- memcpy(&data[PARTIAL_ADD_ESEL_REQ],
- &i_data->eSelExtra[eSELindex],
- dataCpyLen);
-
- // update the offset into the data
- eSELindex = eSELindex + dataCpyLen;
-
- o_cc = IPMI::CC_UNKBAD;
- TRACFBIN( g_trac_ipmi, INFO_MRK"partial_add_esel:", data, len);
- o_err = IPMI::sendrecv(IPMI::partial_add_esel(),o_cc,len,data);
- if(o_err)
- {
- IPMI_TRAC(ERR_MRK "error from partial_add_esel");
- break;
- }
- // as long as we continue to get CC_OK, the reserve sel is good.
- // if the reservation is lost (ie, because something else tried to
- // create a SEL) then the BMC just discards all this data. the
- // errorlog will still be in PNOR and won't get ACKed, so it'll get
- // resent on the next IPL.
- if (o_cc != IPMI::CC_OK)
- {
- IPMI_TRAC(ERR_MRK "failed partial_add_esel, o_cc %02x, eSELindex %02x",
- o_cc, eSELindex);
- break;
- }
- // BMC returns the recordID, it's always the same (unless
- // there's a major BMC bug...)
- storeReserveRecord(esel_recordID,data);
- } // while eSELindex
- if (o_cc == IPMI::CC_OK)
- {
- memcpy(i_data->eselRecord,esel_recordID,sizeof(esel_recordID));
- }
- }while(0);
-
- // if eSEL wasn't created due to an error or callhome, we don't want to continue
- if ((o_err == NULL) && (o_cc == IPMI::CC_OK) && (!i_infoCallHome))
- {
- // caller wants us to NOT create sensor SEL
- if ((i_data->eSel[offsetof(selRecord,sensor_type)] == SENSOR::INVALID_TYPE) &&
- (i_data->eSel[offsetof(selRecord,sensor_number)] == TARGETING::UTIL::INVALID_IPMI_SENSOR)
- )
- {
- IPMI_TRAC(INFO_MRK "Invalid sensor type/number - NOT sending sensor SELs");
- }
- else
- {
- // if the eSEL wasn't created due to a bad completion code, we will
- // still try to send down a SEL that we create, which will contain
- // the eSEL recordID (if it was successful)
- if (data)
- {
- delete [] data;
- }
- len = sizeof(IPMISEL::selRecord);
- data = new uint8_t[len];
-
-
- // send standard SEL event
- if (i_data->selEvent)
- {
- // copy in the SEL event record data
- memcpy(data, i_data->eSel, len);
- // copy the eSEL recordID (if it was created) into the extra data area
- // and mark the event_data1 to indicate this is OEM data
- data[offsetof(selRecord,event_data1)] |= 0xA0;
- data[offsetof(selRecord,event_data2)] = i_data->eselRecord[1];
- data[offsetof(selRecord,event_data3)] = i_data->eselRecord[0];
- }
- else //send OEM SEL event
- {
- // copy in the SEL event record data
- memcpy(data, i_data->oemSel, len);
- data[offsetof(oemSelRecord,event_data5)] = i_data->eselRecord[1];
- data[offsetof(oemSelRecord,event_data6)] =i_data->eselRecord[0];
- }
-
- // use local cc so that we don't corrupt the esel from above
- IPMI::completion_code l_cc = IPMI::CC_UNKBAD;
- TRACFBIN( g_trac_ipmi, INFO_MRK"add_sel:", data, len);
- o_err = IPMI::sendrecv(IPMI::add_sel(),l_cc,len,data);
- if(o_err)
- {
- IPMI_TRAC(ERR_MRK "error from add_sel");
- }
- else if (l_cc != IPMI::CC_OK)
- {
- IPMI_TRAC(ERR_MRK "failed add_sel, l_cc %02x", l_cc);
- }
- else
- {
- // if CC_OK, then len=2 and data contains the recordID of the new SEL
- storeReserveRecord(sel_recordID,data);
- }
- }
- }
-
- if (data)
- {
- delete [] data;
- }
-
- IPMI_TRAC(EXIT_MRK
- "send_esel o_err=%.8X, o_cc=x%.2x, sel recID=x%x%x, esel recID=x%x%x",
- o_err ? o_err->plid() : NULL, o_cc, sel_recordID[1], sel_recordID[0],
- esel_recordID[1], esel_recordID[0]);
-
- return;
-} // send_esel
-
-uint32_t get_sel_time()
-{
- uint8_t *data = NULL;
- size_t len = 0;
- errlHndl_t l_err;
- IPMI::completion_code l_cc = IPMI::CC_UNKBAD;
-
- l_err = IPMI::sendrecv( IPMI::get_sel_time(), l_cc, len, data );
- if( l_err || l_cc != IPMI::CC_OK || len != sizeof(uint32_t) )
- {
- delete l_err;
- delete [] data;
- return 0;
- }
-
- uint32_t timet = le32toh(*reinterpret_cast<uint32_t*>(data));
- delete [] data;
- return timet;
-}
-
-} // IPMISEL
-
-#ifndef __HOSTBOOT_RUNTIME
-/**
- * @brief Constructor
- */
-IpmiSEL::IpmiSEL(void)
- :iv_msgQ(msg_q_create())
-{
- IPMI_TRAC(ENTER_MRK "IpmiSEL ctor");
- task_create(&IpmiSEL::start,NULL);
-}
-
-/**
- * @brief Destructor
- */
-IpmiSEL::~IpmiSEL(void)
-{
- msg_q_destroy(iv_msgQ);
-}
-
-void* IpmiSEL::start(void* unused)
-{
- Singleton<IpmiSEL>::instance().execute();
- return NULL;
-}
-
-/**
- * @brief Entry point of the sel ipmi thread
- */
-//@todo: RTC 119832
-void IpmiSEL::execute(void)
-{
- //Mark as an independent daemon so if it crashes we terminate.
- task_detach();
-
- INITSERVICE::registerShutdownEvent(IPMI_COMP_ID, iv_msgQ,
- IPMISEL::MSG_STATE_SHUTDOWN_SEL,
- INITSERVICE::IPMI_SEL_PRIORITY);
- bool l_terminate = false;
-
- while(!l_terminate)
- {
- msg_t* msg = msg_wait(iv_msgQ);
-
- const IPMISEL::msg_type msg_type =
- static_cast<IPMISEL::msg_type>(msg->type);
-
- // Invert the "default" by checking here. This allows the compiler
- // to warn us if the enum has an unhadled case but still catch
- // runtime errors where msg_type is set out of bounds.
- assert(msg_type <= IPMISEL::MSG_LAST_TYPE,
- "msg_type %d not handled", msg_type);
-
- switch(msg_type)
- {
- case IPMISEL::MSG_SEND_ESEL:
- IPMISEL::process_esel(msg);
- //done with msg
- msg_free(msg);
- break;
-
- case IPMISEL::MSG_STATE_SHUTDOWN:
- IPMI_TRAC(INFO_MRK "ipmisel shutdown event");
- l_terminate = true;
-
- //Respond that we are done shutting down.
- msg_respond(iv_msgQ, msg);
- break;
-
- case IPMISEL::MSG_STATE_SHUTDOWN_SEL:
- IPMI_TRAC(INFO_MRK "ipmisel shutdown message from initservice");
- l_terminate = true;
- msg_respond(iv_msgQ, msg);
- break;
- }
- }
- IPMI_TRAC(EXIT_MRK "message loop");
- return;
-} // execute
-#endif
-
diff --git a/src/usr/ipmi/ipmiselrecord.C b/src/usr/ipmi/ipmiselrecord.C
deleted file mode 100644
index 5d82d4fe3..000000000
--- a/src/usr/ipmi/ipmiselrecord.C
+++ /dev/null
@@ -1,54 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmiselrecord.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2015 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file ipmiselrecord.C
- * @brief code for the IPMI sel record class
- */
-
-#include <ipmi/ipmiif.H>
-
-namespace IPMI
-{
- ///
- /// @brief populate an OEM SEL record from an event read
- /// @param[in] i_raw_event_data, pointer to the read event data
- ///
- void oemSEL::populateFromEvent(uint8_t const* i_raw_event_data)
- {
- iv_record = i_raw_event_data[0] << 8 | i_raw_event_data[1];
- iv_record_type = i_raw_event_data[2];
- iv_timestamp = i_raw_event_data[6] << 24 |
- i_raw_event_data[5] << 16 |
- i_raw_event_data[4] << 8 |
- i_raw_event_data[3];
-
- memcpy(iv_manufacturer, &i_raw_event_data[7], MANUF_LENGTH);
- iv_netfun = i_raw_event_data[10];
- memcpy(iv_cmd, &i_raw_event_data[11], CMD_LENGTH);
-
- return;
- }
-
-};
diff --git a/src/usr/ipmi/ipmisensor.C b/src/usr/ipmi/ipmisensor.C
deleted file mode 100644
index 173f6e546..000000000
--- a/src/usr/ipmi/ipmisensor.C
+++ /dev/null
@@ -1,1763 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmisensor.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
-/* [+] Google Inc. */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file ipmisensor.C
- * @brief IPMI sensor manipulation
- */
-
-#include <ipmi/ipmisensor.H>
-#include <errl/errlentry.H>
-#include <errl/errlmanager.H>
-#include <targeting/common/target.H>
-#include <attributetraits.H>
-#include <targeting/common/utilFilter.H>
-#include <ipmi/ipmi_reasoncodes.H>
-#include <endian.h>
-#include <vpd/pvpdenums.H>
-#include <devicefw/userif.H>
-#include <hdat/hdat.H>
-
-
-extern trace_desc_t * g_trac_ipmi;
-
-namespace SENSOR
-{
-
- //
- // Base class for sensor construction. It is expected that this object will
- // be used as the base for any additional sensors defined.
- //
- SensorBase::SensorBase( TARGETING::SENSOR_NAME i_name,
- const TARGETING::Target * i_target)
- :iv_name(i_name) ,iv_target(i_target)
- {
- // allocate a new message structure to use with our sensors
- // this will be the payload for the IPMI send/sendrecv sensor message.
- iv_msg = new setSensorReadingRequest;
- };
-
- // base class destructor
- SensorBase::~SensorBase()
- {
- // The memory allocated for the set sensor reading command is deleted
- // by the IPMI transport layer. Since we are sending messages
- // asynchronously, the IPMI resource provider deletes the message
- // and there is nothing to delete here.
- };
-
- //
- // Helper function to process completion codes returned from the BMC.
- // If the completion code warrants a PEL the function will build and
- // return an error log with the correct data captured.
- //
- errlHndl_t SensorBase::processCompletionCode( IPMI::completion_code i_rc )
- {
- errlHndl_t l_err = NULL;
-
- IPMI::IPMIReasonCode l_reasonCode;
-
- if( i_rc != IPMI::CC_OK )
- {
- // bad rc from the BMC
- TRACFCOMP(g_trac_ipmi,"completion code 0x%x returned from the BMC"
- " , creating error log", i_rc);
-
- switch(i_rc)
- {
- case SENSOR::CC_SENSOR_READING_NOT_SETTABLE:
- {
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR
- * @reasoncode IPMI::RC_SENSOR_NOT_SETTABLE
- * @userdata1 BMC IPMI Completion code.
- * @userdata2 bytes [0-1]sensor name
- * bytes [2-3]sensor number
- * bytes [4-7]HUID of target.
- * @devdesc Set sensor reading command failed.
- */
- l_reasonCode = IPMI::RC_SENSOR_NOT_SETTABLE;
- TRACFCOMP(g_trac_ipmi,"Attempt to change sensor reading or"
- "set/clear status bits that are not settable"
- " via this command");
- break;
- }
-
- case SENSOR::CC_EVENT_DATA_BYTES_NOT_SETTABLE:
- {
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR
- * @reasoncode IPMI::RC_EVENT_DATA_NOT_SETTABLE
- * @userdata1 BMC IPMI Completion code.
- * @userdata2 bytes[0-3]sensor number
- * bytes[4-7]HUID of target.
- * @devdesc Set sensor reading command failed.
- */
- l_reasonCode = IPMI::RC_EVENT_DATA_NOT_SETTABLE;
- TRACFCOMP(g_trac_ipmi,"Attempted to set event data bytes "
- "but setting event data bytes is not supported for"
- " this sensor");
- break;
- }
-
- case IPMI::CC_CMDSENSOR:
- {
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR
- * @reasoncode IPMI::RC_INVALID_SENSOR_CMD
- * @userdata1 BMC IPMI Completion code.
- * @userdata2 bytes [0-1]sensor name
- * bytes [2-3]sensor number
- * bytes [4-7]HUID of target.
- * @devdesc Command not valid for this sensor.
- */
- l_reasonCode = IPMI::RC_INVALID_SENSOR_CMD;
- TRACFCOMP(g_trac_ipmi,"Command not valid for this sensor");
- break;
- }
-
- case IPMI::CC_BADSENSOR:
- {
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR
- * @reasoncode IPMI::RC_SENSOR_NOT_PRESENT
- * @userdata1 BMC IPMI Completion code.
- * @userdata2 bytes [0-1]sensor name
- * bytes [2-3]sensor number
- * bytes [4-7]HUID of target.
- * @devdesc Requested sensor is not present.
- */
- l_reasonCode = IPMI::RC_SENSOR_NOT_PRESENT;
- TRACFCOMP(g_trac_ipmi,"Requested sensor not present");
- break;
- }
-
- default:
- {
- // lump everything else into a general failure for
- // now.
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR
- * @reasoncode IPMI::RC_SET_SENSOR_FAILURE
- * @userdata1 BMC IPMI Completion code.
- * @userdata2 bytes [0-1]sensor name
- * bytes [2-3]sensor number
- * bytes [4-7]HUID of target.
- * @devdesc Set sensor reading command failed.
- */
- TRACFCOMP(g_trac_ipmi,"Set sensor reading command failed");
- l_reasonCode = IPMI::RC_SET_SENSOR_FAILURE;
- break;
- }
- }
-
- // shift the sensor number into to bytes 0-3 and then
- // or in the HUID to bytes 4-7
- uint32_t sensor_number = getSensorNumber();
- uint32_t huid = TARGETING::get_huid( iv_target );
-
- TRACFCOMP(g_trac_ipmi,"Sensor Number: 0x%X, HUID: 0x%X", sensor_number, huid );
-
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISENSOR,
- l_reasonCode,
- i_rc,
- TWO_UINT32_TO_UINT64(
- TWO_UINT16_TO_UINT32(iv_name,
- sensor_number),
- huid ),
- true);
-
- l_err->collectTrace(IPMI_COMP_NAME);
-
- }
- return l_err;
- }
-
- //
- // Helper function to send the data to the BMC using the correct interface
- // protocol
- //
- errlHndl_t SensorBase::writeSensorData()
- {
-
- errlHndl_t l_err = NULL;
-
- iv_msg->iv_sensor_number = static_cast<uint8_t>(getSensorNumber());
-
- if( iv_msg->iv_sensor_number != TARGETING::UTIL::INVALID_IPMI_SENSOR )
- {
-
- // iv_msg is deleted by the IPMI resource provider.
- l_err = sendSetSensorReading( iv_msg);
-
- if( l_err )
- {
- TRACFCOMP(g_trac_ipmi,"error returned from "
- "sendSetSensorReading() for sensor number 0x%x",
- getSensorNumber());
- }
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"We were not able to find a sensor number in"
- " the IPMI_SENSORS attribute for sensor_name=0x%x "
- "for target with huid=0x%x, skipping call to "
- "sendSetSensorReading()",
- iv_name, TARGETING::get_huid( iv_target ));
-
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR
- * @reasoncode IPMI::RC_SENSOR_NOT_FOUND
- * @userdata1 Returned sensor number.
- * @userdata2 bytes [0-3]sensor name
- * bytes [4-7]HUID of target.
- * @devdesc Requested sensor attribute not found.
- */
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISENSOR,
- IPMI::RC_SENSOR_NOT_FOUND,
- iv_msg->iv_sensor_number,
- TWO_UINT32_TO_UINT64( iv_name,
- TARGETING::get_huid( iv_target ) ),
- true);
-
- delete iv_msg;
- }
-
- return l_err;
- };
-
- //
- // Helper function to set the bit in the assertion/deassertion mask
- // associated with the desired sensor specific offset
- //
- uint16_t SensorBase::setMask( const uint8_t offset, bool swap )
- {
- const uint16_t mask = (0x0001 << offset);
-
- if(swap)
- {
- // need to byte swap the mask (see set sensor reading in spec)
- return le16toh(mask);
- }
- else
- {
- return mask;
- }
-
- };
-
- //
- // Helper function to translate the assertion/deassertion mask into
- // the correct event offset.
- //
- uint8_t SensorBase::getOffset( uint16_t mask )
- {
- // $TODO RTC:117872
- return 0;
- };
-
- // read data from the sensor.
- errlHndl_t SensorBase::readSensorData( getSensorReadingData& o_data)
- {
-
- // get sensor reading command only requires one byte of extra data,
- // which will be the sensor number, the command will return between
- // 3 and 5 bytes of data.
- size_t len = 1;
-
- // need to allocate some memory to hold the sensor number this will be
- // deleted by the IPMI transport layer
- uint8_t * l_data = new uint8_t[len];
-
- l_data[0] = static_cast<uint8_t>(getSensorNumber());
-
- IPMI::completion_code cc = IPMI::CC_UNKBAD;
-
- // o_data will hold the response when this returns
- errlHndl_t l_err = sendrecv(IPMI::get_sensor_reading(), cc, len,
- l_data);
-
- // if we didn't get an error back from the BT interface, but see a
- // bad completion code from the BMC, process the CC to see if we
- // need to create a PEL - if an error occurs sendrcv will clean up
- // l_data for us
- if( l_err == NULL )
- {
- l_err = processCompletionCode( cc );
-
- if( l_err == NULL )
- {
- // populate the output structure with the sensor data
- o_data.completion_code = cc;
-
- o_data.sensor_status = l_data[0];
-
- o_data.sensor_reading = l_data[1];
-
- // bytes 3-5 of the reading are optional and will be dependent
- // on the value of the sensor status byte.
- if( !( o_data.sensor_status &
- ( SENSOR::SENSOR_DISABLED |
- SENSOR::SENSOR_SCANNING_DISABLED )) ||
- ( o_data.sensor_status & SENSOR::READING_UNAVAILABLE ))
- {
- // sensor reading is available
- o_data.event_status =
- (( (uint16_t) l_data[3]) << 8 | l_data[2] );
-
- // spec indicates that the high order bit should be
- // ignored on a read, so lets mask it off now.
- o_data.event_status &= 0x7FFF;
- }
- else
- {
- uint32_t l_sensorNumber = getSensorNumber();
-
- TRACFCOMP(g_trac_ipmi,"Sensor reading not available: status = 0x%x",o_data.sensor_status);
- TRACFCOMP(g_trac_ipmi,"sensor number 0x%x, huid 0x%x",l_sensorNumber ,get_huid(iv_target));
-
- // something happened log an error to indicate the request
- // failed
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR
- * @reasoncode IPMI::RC_SENSOR_READING_NOT_AVAIL
- * @userdata1 sensor status indicating reason for
- * reading not available
- * @userdata2[0:31] sensor number
- * @userdata2[32:64] HUID of target
- *
- * @devdesc Set sensor reading command failed.
- * @custdesc Request to get sensor reading
- * IPMI completion code can be seen
- * in userdata1 field of the log.
- */
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISENSOR,
- IPMI::RC_SENSOR_READING_NOT_AVAIL,
- o_data.sensor_status,
- TWO_UINT32_TO_UINT64( l_sensorNumber,
- TARGETING::get_huid(iv_target)), true);
-
- l_err->collectTrace(IPMI_COMP_NAME);
-
- }
-
- }
-
- delete[] l_data;
- }
- return l_err;
- };
-
- //
- // Asynchronously send a set sensor reading command to the BMC.
- //
- errlHndl_t SensorBase::sendSetSensorReading(
- setSensorReadingRequest * i_data)
- {
-
- size_t l_len = sizeof( setSensorReadingRequest );
-
- // i_data will hold the response when this returns
- errlHndl_t l_err = send(IPMI::set_sensor_reading(),
- l_len, (uint8_t *)i_data);
-
- return l_err;
- }
-
- // return the sensor type and event reading data
- errlHndl_t SensorBase::getSensorType(uint32_t i_sensorNumber,
- uint8_t &o_sensorType,
- uint8_t &o_eventReadingType )
- {
-
- size_t len = 1;
-
- o_sensorType = INVALID_TYPE;
- o_eventReadingType = INVALID_TYPE;
-
- // need to allocate some memory to hold the sensor number this will be
- // deleted by the IPMI transport layer
- uint8_t *l_data = new uint8_t[len];
-
- l_data[0] = i_sensorNumber;
-
- IPMI::completion_code cc = IPMI::CC_UNKBAD;
-
- // l_data will hold the response when this returns
- errlHndl_t l_err = sendrecv(IPMI::get_sensor_type(), cc, len,
- l_data);
-
- // if we didn't get an error back from the BT interface,
- // process the CC to see if we need to create a PEL
- if( l_err == NULL )
- {
- // check the completion code
- if( cc!= IPMI::CC_OK )
- {
- TRACFCOMP(g_trac_ipmi,"bad completion code from BMC=0x%x",cc);
-
- /*@
- * @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid IPMI::MOD_IPMISENSOR
- * @reasoncode IPMI::RC_GET_SENSOR_TYPE_CMD_FAILED
- * @userdata1 BMC IPMI Completion code.
- * @devdesc Request to get sensor type form the bmc
- * failed.
- */
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_INFORMATIONAL,
- IPMI::MOD_IPMISENSOR,
- IPMI::RC_GET_SENSOR_TYPE_CMD_FAILED,
- static_cast<uint64_t>(cc),0, true);
-
- l_err->collectTrace(IPMI_COMP_NAME);
-
-
- }
- else
- {
- // grab the type and reading code to pass back to the caller
- o_sensorType = l_data[0];
-
- // high order bit is reserved
- o_eventReadingType = ( 0x7f & l_data[1]);
-
- }
- delete[] l_data;
- }
- return l_err;
- };
-
-
- /**
- * @brief Returns major type of input sensor name
- *
- * @param[in] i_sensorName
- * Name of the sensor
- *
- * @return Major type of input sensor name
- */
- static inline uint16_t getMajorType(
- const uint16_t i_sensorName)
- {
- return (i_sensorName & SENSOR_NAME_MAJOR_MASK);
- }
-
- /**
- * @brief Returns minor type of input sensor name
- *
- * @param[in] i_sensorName
- * Name of the sensor
- *
- * @return Minor type of input sensor name
- */
- static inline uint16_t getMinorType(
- const uint16_t i_sensorName)
- {
- return (i_sensorName & SENSOR_NAME_MINOR_MASK);
- }
-
- /**
- * @brief Returns whether the supplied sensor record's major type is less
- * than the major type of the supplied sensor name
- *
- * @param[in] i_sensorRecord
- * Sensor record to compare
- *
- * @param[in] i_sensorName
- * Name of the sensor to compare
- *
- * @retval true Major type of sensor record is less than major type of
- * sensor name
- * @retval false Major type of sensor record is not less than major type of
- * sensor name
- */
- static inline bool compare_major(
- const uint16_t (&i_sensorRecord)[2],
- const uint16_t i_sensorName)
- {
- return getMajorType(i_sensorRecord[0]) < getMajorType(i_sensorName);
- }
-
- /**
- * @brief Returns whether the supplied sensor record's major type equals
- * the major type of the supplied sensor name
- *
- * @param[in] i_sensorRecord
- * Sensor record to compare
- *
- * @param[in] i_sensorName
- * Name of the sensor to compare
- *
- * @retval true Major type of sensor record equals major type of
- * sensor name
- * @retval false Major type of sensor record does not equal major type of
- * sensor name
- */
- static inline bool equals_major(
- const uint16_t (&i_sensorRecord)[2],
- const uint16_t i_sensorName)
- {
- return getMajorType(i_sensorRecord[0]) == getMajorType(i_sensorName);
- }
-
- ///
- // FirmwareProgressSensor constructor - uses system target
- //
- FirmwareProgressSensor::FirmwareProgressSensor( )
- :SensorBase(TARGETING::SENSOR_NAME_FW_BOOT_PROGRESS, NULL)
- {
- // message buffer created and initialized in base object.
-
- // assert the system firmware progress offset.
- iv_msg->iv_assertion_mask = setMask( SYSTEM_FIRMWARE_PROGRESS );
- };
-
- //
- // FirmwareProgressSensor destructor
- //
- FirmwareProgressSensor::~FirmwareProgressSensor( )
- {
-
- };
-
- //
- // setBootProgressPhase - update the boot progress sensor of the BMC
- //
- errlHndl_t FirmwareProgressSensor::setBootProgressPhase(
- INITSERVICE::firmwareProgressPhase phase )
- {
- // event data 2 holds the progress info
- iv_msg->iv_event_data[1] = phase;
-
- return writeSensorData();
- };
-
- //
- // RebootCountSensor constructor - uses system target
- //
- RebootCountSensor::RebootCountSensor()
- :SensorBase(TARGETING::SENSOR_NAME_REBOOT_COUNT, NULL)
- {
- // message buffer created and initialized in base object.
-
- }
-
- //
- // RebootCountSensor destructor
- //
- RebootCountSensor::~RebootCountSensor(){};
-
- //
- // setRebootCount - send a new value for the reboot count to the BMC.
- //
- errlHndl_t RebootCountSensor::setRebootCount( uint16_t i_count )
- {
- // adjust the operation to overwrite the sensor reading
- // to the value we send.
- iv_msg->iv_operation = SET_SENSOR_VALUE_OPERATION;
-
- // the Reboot_count sensor is defined as a discrete sensor
- // but the assertion bytes are being used to transfer the count
- // to the bmc, will need to byte swap the data
- iv_msg->iv_assertion_mask = le16toh(i_count);
-
- return writeSensorData();
-
- }
-
- //
- // getRebootCount - get the reboot count from the BMC
- //
- errlHndl_t RebootCountSensor::getRebootCount( uint16_t &o_rebootCount )
- {
-
- // the Reboot_count sensor is defined as a discrete sensor
- // but the assertion bytes are being used to transfer the count
- // from the BMC
- getSensorReadingData l_data;
-
- errlHndl_t l_err = readSensorData( l_data );
-
- if( l_err == NULL )
- {
- // this value is already byteswapped
- o_rebootCount = l_data.event_status;
- }
- return l_err;
-
- }
-
- //
- // RebootControlSensor constructor - uses system target
- //
- RebootControlSensor::RebootControlSensor()
- :SensorBase(TARGETING::SENSOR_NAME_HOST_AUTO_REBOOT_CONTROL, NULL)
- {
- // message buffer created and initialized in base object.
-
- }
-
- //
- // RebootCountSensor destructor
- //
- RebootControlSensor::~RebootControlSensor(){};
-
- //
- // setRebootControl - turn reboots on or off to the BMC
- //
- errlHndl_t RebootControlSensor::setRebootControl(
- autoRebootSetting i_setting )
- {
- // adjust the operation to overwrite the sensor reading
- // to the value we send.
- iv_msg->iv_operation = SET_SENSOR_VALUE_OPERATION;
-
- // the Reboot Control Sensor is defined as a discrete sensor
- // but the assertion bytes are being used to transfer the state
- iv_msg->iv_assertion_mask = le16toh(i_setting);
-
- TRACFCOMP(g_trac_ipmi,"RebootControlSensor::setRebootControl(%d)",
- i_setting);
-
- return writeSensorData();
- }
-
- //
- // getRebootCount - get the reboot setting from the BMC
- //
- errlHndl_t RebootControlSensor::getRebootControl(
- autoRebootSetting &o_setting )
- {
- // the Reboot control sensor is defined as a discrete sensor
- // DISABLE_REBOOT - keep current state (no reboot)
- // ENABLE_REBOOT - Allow analysis of FIRDATA on XSTOP
- getSensorReadingData l_data;
-
- errlHndl_t l_err = readSensorData( l_data );
-
- if( l_err == NULL )
- {
- // Check that this value is a valid enum value
- if ( l_data.event_status == ENABLE_REBOOTS ||
- l_data.event_status == DISABLE_REBOOTS )
- {
- o_setting = static_cast<autoRebootSetting>(l_data.event_status);
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"Unknown reboot control setting: %d",
- l_data.event_status);
-
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR_REBOOTCNTRL
- * @reasoncode IPMI::RC_INVALID_SENSOR_SETTING
- * @userdata1 Invalid reboot control setting
- * @userdata2 <unused>
- * @devdesc The sensor returned an invalid setting
- * @custdesc Unable to find a valid sensor setting.
- */
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISENSOR_REBOOTCNTRL,
- IPMI::RC_INVALID_SENSOR_SETTING,
- l_data.event_status,
- 0,
- false);
- }
- }
- return l_err;
- }
-
-
- //
- // StatusSensor constructor - uses system DIMM/CORE/PROC target
- //
- StatusSensor::StatusSensor( TARGETING::ConstTargetHandle_t i_target )
- :SensorBase(TARGETING::SENSOR_NAME_STATE, i_target)
- {
- iv_functionalOffset = PROC_DISABLED;
- iv_presentOffset = PROC_PRESENCE_DETECTED;
-
- switch ( i_target->getAttr<TARGETING::ATTR_TYPE>() )
- {
- case TARGETING::TYPE_DIMM:
- {
- iv_functionalOffset = MEMORY_DEVICE_DISABLED;
- iv_presentOffset = MEM_DEVICE_PRESENCE_DETECTED;
- iv_name = TARGETING::SENSOR_NAME_DIMM_STATE;
- break;
- }
- case TARGETING::TYPE_MEMBUF:
- {
- iv_functionalOffset = MEMORY_DEVICE_DISABLED;
- iv_presentOffset = MEM_DEVICE_PRESENCE_DETECTED;
- iv_name = TARGETING::SENSOR_NAME_MEMBUF_STATE;
- break;
- }
- case TARGETING::TYPE_PROC:
- iv_name = TARGETING::SENSOR_NAME_PROC_STATE;
- break;
-
- case TARGETING::TYPE_CORE:
- iv_name = TARGETING::SENSOR_NAME_CORE_STATE;
- break;
-
- default:
- TRACFCOMP(g_trac_ipmi,"INF>>No status sensor associated with target type 0x%x",
- i_target->getAttr<TARGETING::ATTR_TYPE>());
- iv_functionalOffset = INVALID_OFFSET;
- iv_presentOffset = INVALID_OFFSET;
- break;
- }
-
- };
-
- //
- // StatusSensor destructor
- //
- //
- StatusSensor::~StatusSensor()
- {};
-
-
- // Convert the input status to the correct sensor offset value, then
- // send the message to the BMC to update the event status for this sensor.
- errlHndl_t StatusSensor::setStatus( statusEnum i_state )
- {
-
- errlHndl_t l_err = NULL;
-
- if( iv_functionalOffset != INVALID_OFFSET
- && iv_presentOffset != INVALID_OFFSET )
- {
- uint16_t func_mask = setMask( iv_functionalOffset );
- uint16_t pres_mask = setMask( iv_presentOffset );
-
- switch ( i_state )
- {
- case NOT_PRESENT:
- // turn off the present bit
- iv_msg->iv_deassertion_mask = pres_mask;
-
- // turn off the disabled bit in case it was on
- iv_msg->iv_deassertion_mask |= func_mask;
- break;
-
- case PRESENT:
- // turn on the present bit
- iv_msg->iv_assertion_mask = pres_mask;
- break;
-
- case FUNCTIONAL:
- // turn off the disabled bit
- iv_msg->iv_deassertion_mask = func_mask;
- break;
-
- case PRESENT_FUNCTIONAL:
- // assert the present bit
- iv_msg->iv_assertion_mask = pres_mask;
- // turn off the disabled bit
- iv_msg->iv_deassertion_mask = func_mask;
- break;
-
- case PRESENT_NONFUNCTIONAL:
- // assert the present bit
- iv_msg->iv_assertion_mask = pres_mask;
- // assert the disabled bit
- iv_msg->iv_assertion_mask |= func_mask;
- break;
-
- case NON_FUNCTIONAL:
- // assert the disabled bit
- iv_msg->iv_assertion_mask = func_mask;
- break;
-
- default:
- // mark as not present
- iv_msg->iv_deassertion_mask = pres_mask;
- iv_msg->iv_assertion_mask = func_mask;
- break;
- }
-
- l_err = writeSensorData();
- }
- return l_err;
-
- };
-
- //**************************************************************************
- // GpuSensor constructor
- //**************************************************************************
- GpuSensor::GpuSensor(TARGETING::SENSOR_NAME i_name, uint16_t i_num,
- TARGETING::ConstTargetHandle_t i_target)
- : StatusSensor(i_target)
-
- {
- /* Note: StatusSensor sets these for processor target */
- //iv_functionalOffset = PROC_DISABLED;
- //iv_presentOffset = PROC_PRESENCE_DETECTED;
-
- // Override iv_name set by parent constructor
- iv_name = i_name;
-
- // 3 numbers possible (1 per GPU) for each name, so save which one
- iv_sensorNumber = i_num;
- };
-
- //**************************************************************************
- // GpuSensor destructor
- //**************************************************************************
- GpuSensor::~GpuSensor()
- {
- }
-
- //**************************************************************************
- // FaultSensor constructor
- //**************************************************************************
-
- FaultSensor::FaultSensor(
- TARGETING::ConstTargetHandle_t i_pTarget)
- : SensorBase(TARGETING::SENSOR_NAME_FAULT, i_pTarget)
- {
- }
-
- //**************************************************************************
- // FaultSensor constructor for associated targets
- //**************************************************************************
-
- FaultSensor::FaultSensor(
- TARGETING::ConstTargetHandle_t i_pTarget,
- const TARGETING::ENTITY_ID i_associatedType)
- : SensorBase(
- static_cast<TARGETING::SENSOR_NAME>(
- TARGETING::SENSOR_NAME_FAULT | i_associatedType),
- i_pTarget)
- {
- }
-
- //**************************************************************************
- // FaultSensor destructor
- //**************************************************************************
-
- FaultSensor::~FaultSensor()
- {
- }
-
- //**************************************************************************
- // FaultSensor::setStatus
- //**************************************************************************
-
- errlHndl_t FaultSensor::setStatus(
- const FAULT_STATE i_faultState)
- {
- errlHndl_t pError = NULL;
-
- switch(i_faultState)
- {
- case FAULT_STATE_ASSERTED:
- iv_msg->iv_assertion_mask = setMask(FAULT_ASSERTED_OFFSET);
- break;
- case FAULT_STATE_DEASSERTED:
- iv_msg->iv_deassertion_mask = setMask(FAULT_ASSERTED_OFFSET);
- break;
- default:
- assert(0,"Caller passed unsupported fault state of 0x%X",
- i_faultState);
- }
-
- pError = writeSensorData();
- if(pError)
- {
- TRACFCOMP(g_trac_ipmi, ERR_MRK " "
- "Failed to write sensor data for sensor name 0x%X",
- iv_name);
- }
-
- return pError;
- }
-
- //
- // OCC Active Sensor - uses occ target
- //
- //
- OCCActiveSensor::OCCActiveSensor( TARGETING::Target * i_pTarget )
- :SensorBase(TARGETING::SENSOR_NAME_OCC_ACTIVE,
- (TARGETING::ConstTargetHandle_t) i_pTarget )
- {
- };
-
- //
- // OCCActiveSensor destructor
- //
- //
- OCCActiveSensor::~OCCActiveSensor(){};
-
- // Convert the input status to the correct sensor offset value, then
- // send the message to the BMC to update the event status for this sensor.
- errlHndl_t OCCActiveSensor::setState( OccStateEnum i_state )
- {
- errlHndl_t l_err = NULL;
-
- // assert the specified state
- iv_msg->iv_assertion_mask = setMask(i_state);
-
- // there are two offsets used with this sensor, when
- // asserting one, we need to deassert the other as only
- // one state is valid at any given time.
- OccStateEnum other_state =
- (i_state == OCC_ACTIVE) ? OCC_NOT_ACTIVE : OCC_ACTIVE;
-
- iv_msg->iv_deassertion_mask = setMask( other_state );
-
- l_err = writeSensorData();
-
- return l_err;
-
- };
-
- // send the message to the BMC to read the event status for this sensor,
- // will return true if the "disabled" state of the sensor is not
- // asserted
- bool OCCActiveSensor::isActive( )
- {
- getSensorReadingData l_data;
-
- bool is_active = false;
-
- // set the mask, but dont swap the bytes since we are using it locally
- // not passing it in the set sensor cmd
- uint16_t mask = setMask( OCC_ACTIVE, false );
-
- errlHndl_t l_err = readSensorData( l_data );
-
- if( l_err == NULL )
- {
- // check if "disabled" offset has been asserted -
- // this would indicate that the OCC was not yet enabled
- if( l_data.event_status & mask )
- {
- is_active = true;
- }
- }
- else
- {
- // commit the error and return "not active" by default
- errlCommit( l_err, IPMI_COMP_ID );
- }
-
- return is_active;
- }
-
-
- //
- // HostStausSensor constructor - uses system target
- //
- //
- HostStatusSensor::HostStatusSensor()
- :SensorBase(TARGETING::SENSOR_NAME_HOST_STATUS, NULL)
- {
-
- };
-
- //
- // HostStatusSensor destructor
- //
- //
- HostStatusSensor::~HostStatusSensor(){};
-
- //
- // updateHostStaus - update the BMC HostStatus sensor with the passed in
- // value.
- //
- //
- errlHndl_t HostStatusSensor::updateHostStatus( hostStatus status )
- {
- iv_msg->iv_operation = SET_SENSOR_VALUE_OPERATION;
- iv_msg->iv_assertion_mask = setMask((uint8_t)status);
-
- return writeSensorData();
- };
-
- //
- // Used to update the sensor status for a specific set of target types
- // currently supported types are TYPE_DIMM, TYPE_MEMBUF, TYPE_CORE,
- // TYPE_PROC. These are virtual sensors where Hostboot updates the
- // present and functional states and the BMC maintains the sensor.
- //
- void updateBMCSensorStatus(TARGETING::TYPE i_type)
- {
-
- TARGETING::TargetHandleList l_tList;
-
- // get all targets of the passed in type, functional or not
- switch( i_type )
- {
-
- case TARGETING::TYPE_DIMM:
- getAllLogicalCards( l_tList, TARGETING::TYPE_DIMM, false );
- break;
-
- case TARGETING::TYPE_MEMBUF:
- getAllChips( l_tList, TARGETING::TYPE_MEMBUF, false );
- break;
-
- case TARGETING::TYPE_PROC:
- getAllChips( l_tList, TARGETING::TYPE_PROC, false );
- break;
-
- case TARGETING::TYPE_CORE:
- getAllChiplets( l_tList, TARGETING::TYPE_CORE, false);
- break;
-
- default:
- assert(0, "invalid target type for BMC update");
-
- }
-
- // have a list of targets now set the status sensor on the BMC for each
- // one.
- for(TARGETING::TargetHandleList::const_iterator pTargetIt =
- l_tList.begin();
- pTargetIt != l_tList.end();
- ++pTargetIt )
- {
-
- StatusSensor::statusEnum l_status
- = StatusSensor::PRESENT_FUNCTIONAL;
-
- // create a status sensor for our needs
- StatusSensor l_sensor((*pTargetIt));
-
- TARGETING::HwasState l_state =
- (*pTargetIt)->getAttr<TARGETING::ATTR_HWAS_STATE>();
-
- if( l_state.present == true )
- {
- if( l_state.functional == false )
- {
- l_status = StatusSensor::PRESENT_NONFUNCTIONAL;
- }
- }
- else
- {
- l_status = StatusSensor::NOT_PRESENT;
- }
-
- // send the status to the BMC
- errlHndl_t l_err = l_sensor.setStatus( l_status );
-
- // commit the error and move to the next target
- if( l_err )
- {
- errlCommit( l_err, IPMI_COMP_ID );
- }
- }
-
- }
-
- void updateBMCFaultSensorStatus(void)
- {
- TARGETING::ATTR_IPMI_SENSORS_type noSensors = {{0}};
-
- // No sensor attribute is all 0's; therefore if a sensor attribute is
- // found and is not all zeros (using the predicate value inversion
- // feature) then the sensor attribute has potential
- // sensors to iterate through
- TARGETING::PredicateAttrVal<TARGETING::ATTR_IPMI_SENSORS>
- hasSensors(noSensors,true);
- TARGETING::TargetRangeFilter targetsWithSensorsItr(
- TARGETING::targetService().begin(),
- TARGETING::targetService().end(),
- &hasSensors);
- for (; targetsWithSensorsItr; ++targetsWithSensorsItr)
- {
- // Cache the target for ease of reading/usage
- TARGETING::TargetHandle_t pTarget = *targetsWithSensorsItr;
-
- TARGETING::ATTR_IPMI_SENSORS_type sensors = {{0}};
- assert(pTarget->tryGetAttr<TARGETING::ATTR_IPMI_SENSORS>(sensors));
-
- // Derive number of sensor records by dividing attribute size by
- // size of each sensor record
- uint16_t sensorRows = (sizeof(sensors)/sizeof(sensors[0]));
-
- // Ceate an iterator pointing to the first element of the array
- uint16_t (*begin)[2] = &sensors[0];
-
- // Using the number entries as the index into the array will set the
- // end iterator to the correct position (one entry past the last
- // element of the array)
- uint16_t (*end)[2] = &sensors[sensorRows];
-
- // Locate the first record that could possibly match the criteria
- uint16_t (*ptr)[2] =
- std::lower_bound(begin, end,
- TARGETING::SENSOR_NAME_FAULT, &compare_major);
-
- // Process any match, and all remaining matches after that, until
- // there is no additional match. Here we are matching the major
- // sensor type only
- while( (ptr != end)
- && ( getMajorType((*ptr)[0])
- == TARGETING::SENSOR_NAME_FAULT ))
- {
- TRACFCOMP(g_trac_ipmi, INFO_MRK " "
- "Found fault sensor name 0x%X and ID 0x%X for HUID 0x%X",
- (*ptr)[0], (*ptr)[1], TARGETING::get_huid(pTarget));
-
- FaultSensor faultSensor(pTarget,
- static_cast<TARGETING::ENTITY_ID>(
- getMinorType((*ptr)[0])));
-
- errlHndl_t pError = faultSensor.setStatus(
- FaultSensor::FAULT_STATE_DEASSERTED);
- if(pError)
- {
- TRACFCOMP(g_trac_ipmi, ERR_MRK " "
- "Failed setting fault sensor name 0x%X and ID 0x%X for "
- "HUID 0x%X",
- (*ptr)[0], (*ptr)[1], TARGETING::get_huid(pTarget));
- errlCommit(pError, IPMI_COMP_ID);
- }
-
- ++ptr;
- }
- }
- }
-
- void updateBMCSensorStatus()
- {
-
- // send status of all MEMBUF targets
- updateBMCSensorStatus(TARGETING::TYPE_MEMBUF);
-
- // send status of all DIMM targets
- updateBMCSensorStatus(TARGETING::TYPE_DIMM);
-
- // send status for all PROC targets
- updateBMCSensorStatus(TARGETING::TYPE_PROC);
-
- updateBMCSensorStatus(TARGETING::TYPE_CORE);
-
- // Send status for all simple fault sensors in the system
- updateBMCFaultSensorStatus();
- };
-
- // returns a sensor number for the FRU based on input target type
- // there are currently 4 frus defined system, backplane, DIMM, PROC
- //
- uint32_t getFaultSensorNumber( TARGETING::ConstTargetHandle_t i_pTarget )
- {
- TRACDCOMP(g_trac_ipmi,">>getFaultSensorNumber()");
-
- TARGETING::TYPE l_type = i_pTarget->getAttr<TARGETING::ATTR_TYPE>();
-
- uint32_t l_sensor_number = TARGETING::UTIL::INVALID_IPMI_SENSOR;
-
- switch( l_type )
- {
-
- case TARGETING::TYPE_SYS:
- {
- TRACDCOMP(g_trac_ipmi, "returning the \"System Event\" sensor\n");
- l_sensor_number = TARGETING::UTIL::getSensorNumber(
- i_pTarget,
- TARGETING::SENSOR_NAME_SYSTEM_EVENT );
-
- TRACDCOMP(g_trac_ipmi,"Sensor Number = 0x%x", l_sensor_number);
- break;
- }
-
- case TARGETING::TYPE_NODE:
- {
- TRACDCOMP(g_trac_ipmi, "returning the \"BACKPLANE_FAULT\" sensor\n");
- l_sensor_number = TARGETING::UTIL::getSensorNumber(
- i_pTarget,
- TARGETING::SENSOR_NAME_BACKPLANE_FAULT );
-
- TRACDCOMP(g_trac_ipmi,"Sensor Number = 0x%x", l_sensor_number);
- break;
- }
-
- // these targets have specific status sensors
- case TARGETING::TYPE_DIMM:
- case TARGETING::TYPE_MEMBUF:
- case TARGETING::TYPE_PROC:
- {
- l_sensor_number =
- StatusSensor(i_pTarget).getSensorNumber();
-
- TRACDCOMP(g_trac_ipmi,"Sensor Number = 0x%x", l_sensor_number);
- break;
- }
-
- default:
- {
-
- TARGETING::EntityPath l_targetPath =
- i_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>();
-
- // chop off the last part and go again.
- l_targetPath.removeLast();
-
- TARGETING::TargetHandle_t l_target = NULL;
- l_target =
- TARGETING::targetService().toTarget(l_targetPath);
-
- l_sensor_number = getFaultSensorNumber(
- static_cast<TARGETING::ConstTargetHandle_t>(l_target));
-
- break;
- }
- }
-
- TRACDCOMP(g_trac_ipmi,"<<getFaultSensorNumber() returning sensor number %#x", l_sensor_number);
-
- return l_sensor_number;
- }
-
- // interface to retrieve the APSS channel sensor numbers.
- errlHndl_t getAPSSChannelSensorNumbers(
- const uint32_t (* &o_sensor_numbers)[16])
- {
-
- TARGETING::TargetHandle_t l_sys;
-
- // get the "system error" sensor number associated with the
- // system target.
-
- TARGETING::targetService().getTopLevelTarget(l_sys);
-
- static TARGETING::ATTR_ADC_CHANNEL_SENSOR_NUMBERS_type
- apss_sensors;
-
- if( l_sys->tryGetAttr<TARGETING::
- ATTR_ADC_CHANNEL_SENSOR_NUMBERS>(apss_sensors) )
- {
- o_sensor_numbers = &apss_sensors;
- }
- else
- {
- // need that attribute or things dont work
- assert(0,"Missing ADC_CHANNEL_SENSOR_NUMBERS attribute");
- }
-
- return NULL;
- }
-
- uint16_t getSensorOffsets( TARGETING::SENSOR_NAME i_name,
- sensorReadingType &o_readType )
- {
-
- uint16_t offsets = 0;
-
- // most of our sensors use generic sensor specific reading types
- // so use that as the default value
- o_readType = SENSOR_SPECIFIC;
-
- // sensor type is lower byte of sensor name, if we dont match
- // based on name, then try the sensor type
- uint16_t t = ( i_name >> 8 ) & 0x00FF;
-
- switch( i_name )
- {
- case TARGETING::SENSOR_NAME_FW_BOOT_PROGRESS:
- {
- offsets = ( 1 << SYSTEM_FIRMWARE_PROGRESS );
- break;
- }
- case TARGETING::SENSOR_NAME_OCC_ACTIVE:
- {
- offsets = ( 1 << DEVICE_DISABLED ) |
- ( 1 << DEVICE_ENABLED );
- o_readType = DIGITAL_ENABLE_DISABLE;
- break;
- }
- case TARGETING::SENSOR_NAME_HOST_STATUS:
- {
- offsets = ( 1 << S0_G0_WORKING ) |
- ( 1 << G5_SOFT_OFF ) |
- ( 1 << LEGACY_ON );
- break;
- }
- case TARGETING::SENSOR_NAME_PCI_ACTIVE:
- case TARGETING::SENSOR_NAME_OS_BOOT:
- {
- // default all offsets enabled
- offsets = 0x7FFF;
- break;
- }
-
- default:
- {
- // try sensor type
- switch (t)
- {
- case TARGETING::SENSOR_TYPE_FAULT:
- offsets = ( 1 << ASSERTED );
- o_readType = DIGITAL_ASSERT_DEASSERT;
- break;
-
- case TARGETING::SENSOR_TYPE_PROCESSOR:
- offsets = ( 1 << PROC_PRESENCE_DETECTED ) |
- ( 1 << PROC_DISABLED ) |
- ( 1 << IERR );
- break;
-
- case TARGETING::SENSOR_TYPE_MEMORY:
- offsets = ( 1 << MEMORY_DEVICE_DISABLED ) |
- ( 1 << MEM_DEVICE_PRESENCE_DETECTED );
- break;
- default:
- offsets = 0;
- o_readType = THRESHOLD;
- break;
- }
-
- }
- }
-
- return offsets;
- }
-
- uint8_t getBackPlaneFaultSensor()
- {
- TARGETING::TargetHandle_t sys = NULL;
- TARGETING::TargetHandleList nodes;
- TARGETING::targetService().getTopLevelTarget(sys);
- assert(sys != NULL);
- getChildAffinityTargets(nodes, sys, TARGETING::CLASS_ENC,
- TARGETING::TYPE_NODE);
- assert(!nodes.empty());
-
- //Backplane sensor ID
- return TARGETING::UTIL::getSensorNumber(nodes[0],
- TARGETING::SENSOR_NAME_BACKPLANE_FAULT);
- }
-
- /**
- * @brief All sensors returned cfgID bit
- */
- static const uint16_t NVCFG_ALL_SENSORS_RETURNED = 0xFFFF;
-
- /**
- * @brief Helper function to getGpuSensors()
- * NV keyword tells us what backplane is installed,
- * thus what GPUs are supported
- *
- * @param[out] returns NV keyword in bitwise format
- *
- * @return Error log handle if a deviceRead fails
- */
- errlHndl_t getNVCfgIDBit(uint16_t & o_cfgID_bitwise)
- {
- static uint16_t L_NV_bits = 0;
- errlHndl_t l_err = nullptr;
-
- if (L_NV_bits == 0)
- {
- // grab system enclosure node
- TARGETING::TargetHandle_t l_sys = NULL;
- TARGETING::TargetHandleList l_nodeTargets;
- TARGETING::targetService().getTopLevelTarget(l_sys);
- assert(l_sys != NULL);
- getChildAffinityTargets(l_nodeTargets, l_sys, TARGETING::CLASS_ENC,
- TARGETING::TYPE_NODE);
- assert(!l_nodeTargets.empty());
-
- // get keyword size first
- PVPD::pvpdRecord l_Record = PVPD::VNDR;
- PVPD::pvpdKeyword l_KeyWord = PVPD::NV;
- size_t l_nvKwdSize = 0;
- l_err = deviceRead(l_nodeTargets[0],NULL,l_nvKwdSize,
- DEVICE_PVPD_ADDRESS(l_Record,l_KeyWord));
- if (!l_err)
- {
- if (l_nvKwdSize == sizeof(HDAT::hdatNVKwdStruct_t))
- {
- uint8_t l_kwd[l_nvKwdSize] = {0};
- // now read the keyword
- l_err = deviceRead(l_nodeTargets[0],l_kwd,l_nvKwdSize,
- DEVICE_PVPD_ADDRESS(l_Record,l_KeyWord));
- if (!l_err)
- {
- HDAT::hdatNVKwdStruct_t * NVptr =
- reinterpret_cast<HDAT::hdatNVKwdStruct_t*>(l_kwd);
-
- // Valid NV keyword config has NV00 as magic header
- if ( !memcmp((char*)&(NVptr->magic),"NV00", 4) )
- {
- uint8_t cfgID = NVptr->config;
- if (cfgID < 16) // maximum setting (bits 0-15)
- {
- L_NV_bits = 0x0001 << cfgID;
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"getNVCfgIDBit(): Invalid NV config 0x%02X", cfgID);
- }
- }
- else
- {
- TRACFCOMP(g_trac_ipmi, "Invalid NV magic header: 0x%.8X", NVptr->magic);
- TRACFBIN(g_trac_ipmi, "NV KEYWORD", l_kwd, l_nvKwdSize);
- }
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,ERR_MRK"%.8X Error getting VNDR record data",l_err->eid());
- }
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"Invalid NV keyword size: %d, expected %d",l_nvKwdSize,sizeof(HDAT::hdatNVKwdStruct_t));
- }
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,ERR_MRK"%.8X Error getting VNDR record size",l_err->eid());
- }
- }
-
- o_cfgID_bitwise = L_NV_bits;
-
- return l_err;
- }
-
- /**
- * @brief Grab the GPU sensor type IDs for a particular processor target
- *
- * Will return all sensor ids that match the type for a given target.
- *
- * @param[in] - i_proc - processor target
- * @param[in] - i_type - Functional/state, gpucoretemp, gpumemtemp
- * @param[out] - o_num_ids - number of valid IDs returned in o_ids
- * @param[out] - o_ids - ordered list of sensor IDs
- *
- * @return Errorlog handle
- */
- errlHndl_t getGpuSensors( TARGETING::Target* i_proc,
- HWAS::sensorTypeEnum i_type,
- uint8_t & o_num_ids,
- uint32_t o_ids[MAX_GPU_SENSORS_PER_PROCESSOR] )
- {
- static uint16_t L_obus_cfgID_bit = 0;
- errlHndl_t l_errl = nullptr;
-
- // default to no ids returned
- o_num_ids = 0;
-
- TARGETING::AttributeTraits<TARGETING::ATTR_GPU_SENSORS>::Type
- l_sensorArray;
-
- bool foundSensors = i_proc->tryGetAttr<TARGETING::ATTR_GPU_SENSORS>
- (l_sensorArray);
-
- // Verify we are getting non-default values
- if (foundSensors && l_sensorArray[0][0] != 0)
- {
- // Figure out which backplane we have
- // Only read NV keyword once (if possible)
- if (L_obus_cfgID_bit == 0)
- {
- l_errl = getNVCfgIDBit(L_obus_cfgID_bit);
- if (l_errl || (L_obus_cfgID_bit == 0))
- {
- delete l_errl;
- l_errl = nullptr;
- // default to full list of GPU sensors
- L_obus_cfgID_bit = NVCFG_ALL_SENSORS_RETURNED;
- }
- }
-
- uint32_t elementCount = (sizeof(l_sensorArray)/
- sizeof(l_sensorArray[0]));
- TRACFCOMP(g_trac_ipmi,"getGpuSensors() -> GPU_SENSORS array size = %d, cfgBit = 0x%x",
- elementCount, L_obus_cfgID_bit);
-
- // verify array index won't exceed output array (o_ids)
- assert(elementCount <= MAX_GPU_SENSORS_PER_PROCESSOR);
-
- // now cycle through each GPU row
- for (uint32_t index = 0; index < elementCount; index++)
- {
- uint16_t * row_ptr = &l_sensorArray[index][0];
-
- TRACFCOMP(g_trac_ipmi,"getGpuSensors() -> ROW %d, 0x%04X, 0x%X, 0x%04X, 0x%X, 0x%04X, 0x%X, 0x%X",
- index, row_ptr[0], row_ptr[1], row_ptr[2],
- row_ptr[3], row_ptr[4], row_ptr[5], row_ptr[6]);
-
- // Include Sensor if the GPU is present in the current OBUS_CFG
- if ( (L_obus_cfgID_bit == NVCFG_ALL_SENSORS_RETURNED) ||
- ((L_obus_cfgID_bit &
- row_ptr[TARGETING::GPU_SENSOR_ARRAY_OBUS_CFG_OFFSET])
- == L_obus_cfgID_bit) )
- {
- switch(i_type)
- {
- case HWAS::GPU_FUNC_SENSOR:
- o_ids[index] =
- row_ptr[TARGETING::GPU_SENSOR_ARRAY_FUNC_ID_OFFSET];
- o_num_ids++;
- break;
- case HWAS::GPU_MEMORY_TEMP_SENSOR:
- o_ids[index] =
- row_ptr[TARGETING::GPU_SENSOR_ARRAY_MEM_TEMP_ID_OFFSET];
- o_num_ids++;
- break;
- case HWAS::GPU_TEMPERATURE_SENSOR:
- o_ids[index] =
- row_ptr[TARGETING::GPU_SENSOR_ARRAY_TEMP_ID_OFFSET];
- o_num_ids++;
- break;
- default:
- TRACFCOMP(g_trac_ipmi,"getGpuSensors() -> unknown sensor type 0x%02X", i_type);
- o_ids[index] = TARGETING::UTIL::INVALID_IPMI_SENSOR;
- }
- }
- else
- {
- o_ids[index] = TARGETING::UTIL::INVALID_IPMI_SENSOR;
- }
- TRACFCOMP(g_trac_ipmi,
- "getGpuSensors() -> o_id[%d] = 0x%X", index, o_ids[index]);
- } // end of for loop
- } // end of if check for non-default values
-
- return NULL;
- } // end getGpuSensors()
-
-
- /**
- * @brief Helper function that sends GPU sensor status to BMC
- *
- * @param[in] sensor name (IPMI_SENSOR_TYPE with IPMI_ENTITY_ID)
- * @param[in] sensor id number
- * @param[in] processor target
- * @param[in] status to send for the identified GPU sensor
- */
- void sendGpuSensorStatus(uint16_t i_sensor_name_value,
- uint16_t i_sensor_id,
- TARGETING::ConstTargetHandle_t i_target,
- StatusSensor::statusEnum & i_status)
- {
- TRACFCOMP(g_trac_ipmi, "sendGpuSensorStatus(0x%0X, 0x%X, Target 0x%X, status: %d)",
- i_sensor_name_value, i_sensor_id,
- TARGETING::get_huid(i_target), i_status);
-
- TARGETING::SENSOR_NAME l_sensor_name;
- switch(i_sensor_name_value)
- {
- case TARGETING::SENSOR_NAME_GPU_TEMP:
- l_sensor_name = TARGETING::SENSOR_NAME_GPU_TEMP;
- break;
- case TARGETING::SENSOR_NAME_GPU_STATE:
- l_sensor_name = TARGETING::SENSOR_NAME_GPU_STATE;
- break;
- case TARGETING::SENSOR_NAME_GPU_MEM_TEMP:
- l_sensor_name = TARGETING::SENSOR_NAME_GPU_MEM_TEMP;
- break;
- default:
- TRACFCOMP(g_trac_ipmi, "sendGpuSensorStatus(0x%0X, 0x%X) - unknown GPU sensor name",
- i_sensor_name_value, i_sensor_id);
- l_sensor_name = TARGETING::SENSOR_NAME_FAULT;
- break;
- }
-
- // Only update if we found a valid gpu sensor name
- if (l_sensor_name != TARGETING::SENSOR_NAME_FAULT)
- {
- // create a GPU status sensor for our needs
- GpuSensor l_sensor(l_sensor_name, i_sensor_id, i_target);
-
- // send the status to the BMC
- errlHndl_t l_err = l_sensor.setStatus( i_status );
-
- // commit the error and move to the next target
- if( l_err )
- {
- errlCommit( l_err, IPMI_COMP_ID );
- }
- }
- }
-
- /**
- * @brief Updates GPU sensor status for GPUs on this
- * particular processor target
- *
- * @param[in] - i_proc - processor target
- * @param[in] - i_gpu_status - status of GPU0, GPU1 and GPU2
- */
- void updateGpuSensorStatus( TARGETING::Target* i_proc,
- StatusSensor::statusEnum i_gpu_status[MAX_PROCESSOR_GPUS] )
- {
- uint16_t obus_cfgID_bit = 0;
-
- TARGETING::AttributeTraits<TARGETING::ATTR_GPU_SENSORS>::Type
- l_sensorArray;
-
- bool foundSensors = i_proc->tryGetAttr<TARGETING::ATTR_GPU_SENSORS>
- (l_sensorArray);
-
- // Verify we are getting non-default values
- if (foundSensors && (l_sensorArray[0][0] != 0))
- {
- // Figure out which backplane we have
- // Only read NV keyword once (if possible)
- errlHndl_t l_errl = getNVCfgIDBit(obus_cfgID_bit);
- if (l_errl || (obus_cfgID_bit == 0))
- {
- // default to all sensors
- obus_cfgID_bit = NVCFG_ALL_SENSORS_RETURNED;
- delete l_errl;
- }
-
- uint32_t elementCount = (sizeof(l_sensorArray)/
- sizeof(l_sensorArray[0]));
- TRACDCOMP(g_trac_ipmi,"updateGpuSensorStatus() -> array size = %d, cfgBit = 0x%x",
- elementCount, obus_cfgID_bit);
-
- // verify array index won't exceed output array (o_ids)
- assert(elementCount <= MAX_PROCESSOR_GPUS);
-
- // now cycle through each GPU row
- for (uint8_t index = 0; index < MAX_PROCESSOR_GPUS; index++)
- {
- uint16_t * sensor_row_ptr = &l_sensorArray[index][0];
- StatusSensor::statusEnum newStatus = i_gpu_status[index];
-
- // Include Sensor if the GPU is present in the current OBUS_CFG
- if ( (obus_cfgID_bit == NVCFG_ALL_SENSORS_RETURNED) ||
- ((obus_cfgID_bit &
- sensor_row_ptr[TARGETING::GPU_SENSOR_ARRAY_OBUS_CFG_OFFSET])
- == obus_cfgID_bit) )
- {
- // Only update the GPU status sensors, skip temperature ones
- // GPU core Status/Functional Sensor
- uint16_t sensor_name =
- sensor_row_ptr[TARGETING::GPU_SENSOR_ARRAY_FUNC_OFFSET];
- uint16_t sensor_id =
- sensor_row_ptr[TARGETING::GPU_SENSOR_ARRAY_FUNC_ID_OFFSET];
- sendGpuSensorStatus(sensor_name,sensor_id,i_proc,newStatus);
- }
- } // end of GPU loop
- } // end of if check for non-default values
- } // end of updateGpuSensorStatus()
-
-
- //
- // HbVolatileSensor constructor - uses system target
- //
- HbVolatileSensor::HbVolatileSensor()
- :SensorBase(TARGETING::SENSOR_NAME_HB_VOLATILE, NULL)
- {
- // message buffer created and initialized in base object.
- }
-
- //
- // HbVolatileSensor destructor
- //
- HbVolatileSensor::~HbVolatileSensor(){};
-
- //
- // setHbVolatile - tell BMC to make hostboot volatile memory
- // (volatile(2) or not(1))
- //
- errlHndl_t HbVolatileSensor::setHbVolatile( hbVolatileSetting i_setting )
- {
- // adjust the operation to overwrite the sensor reading
- // to the value we send.
- iv_msg->iv_operation = SET_SENSOR_VALUE_OPERATION;
-
- // the HB_VOLATILE Sensor is defined as a discrete sensor
- // but the assertion bytes are being used to transfer the state
- iv_msg->iv_assertion_mask = le16toh(i_setting);
-
- TRACFCOMP(g_trac_ipmi,"HbVolatileSensor::setHbVolatile(%d)",
- i_setting);
-
- return writeSensorData();
- }
-
- //
- // getHbVolatile - get the HB volatile memory setting from the BMC
- //
- errlHndl_t HbVolatileSensor::getHbVolatile( hbVolatileSetting &o_setting )
- {
- // the HB_VOLATILE sensor is defined as a discrete sensor
- getSensorReadingData l_data;
-
- errlHndl_t l_err = readSensorData( l_data );
-
- if( l_err == nullptr )
- {
- // check if in valid range of hbVolatileSetting enums
- if ( l_data.event_status == ENABLE_VOLATILE ||
- l_data.event_status == DISABLE_VOLATILE )
- {
- o_setting = static_cast<hbVolatileSetting>(l_data.event_status);
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"Unknown hb volatile setting: %d",
- l_data.event_status);
-
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMISENSOR_HBVOLATILE
- * @reasoncode IPMI::RC_INVALID_SENSOR_SETTING
- * @userdata1 Invalid hb volatile control setting
- * @userdata2 <unused>
- * @devdesc The sensor returned an invalid setting
- * @custdesc Unable to find a valid sensor setting.
- */
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMISENSOR_HBVOLATILE,
- IPMI::RC_INVALID_SENSOR_SETTING,
- l_data.event_status,
- 0,
- false);
- }
- }
- return l_err;
- }
-
-}; // end name space
diff --git a/src/usr/ipmi/ipmiwatchdog.C b/src/usr/ipmi/ipmiwatchdog.C
deleted file mode 100644
index 42da2a5ba..000000000
--- a/src/usr/ipmi/ipmiwatchdog.C
+++ /dev/null
@@ -1,204 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/ipmiwatchdog.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
-/* [+] Google Inc. */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-#ifndef __IPMIWATCHDOG_IPMIWATCHDOG_C
-#define __IPMIWATCHDOG_IPMIWATCHDOG_C
-/**
- * @file ipmiwatchdog.C
- *
- * Ipmi watchdog timer
- *
- */
-
-/******************************************************************************/
-// Includes
-/******************************************************************************/
-#include <stdint.h>
-#include <errl/errlentry.H>
-#include <ipmi/ipmiwatchdog.H>
-#include <ipmi/ipmiif.H>
-#include <sys/time.h>
-#include <time.h>
-
-/******************************************************************************/
-// Globals/Constants
-/******************************************************************************/
-// Defined in ipmidd.C
-extern trace_desc_t * g_trac_ipmi;
-#define IPMI_TRAC(printf_string,args...) \
- TRACFCOMP(g_trac_ipmi,"wd: " printf_string,##args)
-
-namespace IPMIWATCHDOG
-{
-
-// Needed for watchdog resets in case the BMC side becomes uninitialized and we
-// need to reinitialize it
-static bool g_set_once = false;
-static uint16_t g_countdown_secs;
-static uint8_t g_timer_use;
-static TIMER_ACTIONS g_timer_action;
-static TIMER_USE_CLR_FLAGS g_timer_clr_flag;
-
-/******************************************************************************/
-// Functions
-/******************************************************************************/
-
-
-errlHndl_t setWatchDogTimer( const uint16_t i_countdown_secs,
- const uint8_t i_timer_use,
- const TIMER_ACTIONS i_timer_action,
- const TIMER_USE_CLR_FLAGS i_timer_clr_flag)
-{
- // Save the latest values so that reset actions can setup the timer
- // if the BMC goes away.
- g_set_once = true;
- g_countdown_secs = i_countdown_secs;
- g_timer_use = i_timer_use;
- g_timer_action = i_timer_action;
- g_timer_clr_flag = i_timer_clr_flag;
-
- // Convert secs into lsb and msb values
- // the ipmi spec uses the count which is 100ms/count
- static const uint16_t ms_per_count = 100;
- static const uint8_t bits_to_shift_for_nxt_byte = 8;
- static const uint8_t byte_mask = 0xFF;
-
- uint16_t countdown = (i_countdown_secs * MS_PER_SEC)
- / ms_per_count;
-
- uint8_t init_countdown_lsb = static_cast<uint8_t>
- (countdown & byte_mask);
-
- uint8_t init_countdown_msb = static_cast<uint8_t>(
- (countdown >> bits_to_shift_for_nxt_byte)
- & byte_mask);
-
-
- size_t len = 6; // IPMI spec has request data at 6 bytes
-
- //create request data buffer
- uint8_t* data = new uint8_t[len];
-
- data[0] = i_timer_use; // byte 1 timer use
- data[1] = i_timer_action; // byte 2 timer actions
- data[2] = 0x00; // byte 3 pre-interval timeout in secs
- data[3] = i_timer_clr_flag; // byte 4 timer use flags to clear
- data[4] = init_countdown_lsb; // byte 5 initial countdown timer LSByte
- data[5] = init_countdown_msb; // byte 6 initial countdown timer MSByte
-
- IPMI_TRAC( "setWatchDogTimer : sec=%d, use=%d, act=%d, clr=%d",
- i_countdown_secs,
- i_timer_use,
- i_timer_action,
- i_timer_clr_flag );
- return IPMI::send(IPMI::set_watchdog(), len, data);
-
-}
-
-
-errlHndl_t resetWatchDogTimer()
-{
- errlHndl_t err_ipmi = NULL;
-
- // Limit the amount of sent watchdog resets to once per second to make
- // sure that we don't overload the BMC with resets during quickly
- // completing ISTEPs. For simplicity we only compare the tv_sec so
- // the grace period may be almost 2 seconds.
- static uint64_t last_reset_sec;
- timespec_t now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- if (last_reset_sec + 1 >= now.tv_sec)
- {
- return NULL;
- }
- last_reset_sec = now.tv_sec;
-
- // reset command does not take any request data
- size_t len = 0;
- uint8_t* data = NULL;
-
-
- do
- {
- IPMI_TRAC( "resetWatchDogTimer" );
-
- IPMI::completion_code cc;
- err_ipmi = IPMI::sendrecv(IPMI::reset_watchdog(), cc, len, data);
- delete[] data;
-
- if(err_ipmi)
- {
- //got an error sending IPMI msg
- //progate error upstream.
- break;
- }
-
- // Make sure we don't have an uninitialized watchdog
- // openbmc will always start the watchdog regardless of us
- // initializing it. If we don't initialize it, it can eventually
- // time out on us
- if (g_set_once && cc == IPMI::CC_CMDSPC1)
- {
- err_ipmi = setWatchDogTimer(g_countdown_secs,
- g_timer_use | DO_NOT_STOP,
- g_timer_action, g_timer_clr_flag);
-
- if (err_ipmi)
- {
- //got an error sending IPMI msg
- //progate error upstream.
- break;
- }
-
- // Make sure to issue a reset after initialization to start
- // the timer if it isn't already. We don't care about the return
- // value of this message since we can't recurse forever. If we
- // fail here, later resets should handle reconfiguring the
- // watchdog if it isn't critically broken.
- len = 0;
- data = NULL;
- err_ipmi = IPMI::send(IPMI::reset_watchdog(), len, data);
-
- if(err_ipmi)
- {
- //got an error sending IPMI msg
- //progate error upstream.
- break;
- }
- }
-
- // We don't care about any other types of errors as the watchdog
- // will just trip in these cases.
- break;
- }
- while(0);
-
- return err_ipmi;
-}
-
-
-} // namespace
-
-#endif
diff --git a/src/usr/ipmi/makefile b/src/usr/ipmi/makefile
deleted file mode 100644
index 50638b522..000000000
--- a/src/usr/ipmi/makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/usr/ipmi/makefile $
-#
-# OpenPOWER HostBoot Project
-#
-# Contributors Listed Below - COPYRIGHT 2011,2016
-# [+] International Business Machines Corp.
-#
-#
-# 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.
-#
-# IBM_PROLOG_END_TAG
-ROOTPATH = ../../..
-MODULE = ipmi
-
-#include common ojects between hostboot and runtime hostboot
-include ipmi.mk
-
-OBJS += ipmimsg.o
-OBJS += $(if $(CONFIG_BMC_BT_LPC_IPMI),ipmibt.o)
-OBJS += ipmirp.o
-OBJS += $(if $(CONFIG_BMC_BT_LPC_IPMI),ipmidd.o)
-OBJS += ipmifru.o
-OBJS += ipmiconfig.o
-OBJS += ipmiwatchdog.o
-OBJS += ipmifruinv.o
-OBJS += ipmipowerstate.o
-OBJS += ipmiselrecord.o
-OBJS += ipmichassiscontrol.o
-
-SUBDIRS += runtime.d
-#SUBDIRS += test.d
-
-include ${ROOTPATH}/config.mk
diff --git a/src/usr/ipmi/runtime/makefile b/src/usr/ipmi/runtime/makefile
deleted file mode 100644
index 6f49d9ef1..000000000
--- a/src/usr/ipmi/runtime/makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/usr/ipmi/runtime/makefile $
-#
-# OpenPOWER HostBoot Project
-#
-# Contributors Listed Below - COPYRIGHT 2015
-# [+] International Business Machines Corp.
-#
-#
-# 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.
-#
-# IBM_PROLOG_END_TAG
-HOSTBOOT_RUNTIME = 1
-ROOTPATH = ../../../..
-MODULE = ipmi_rt
-
-#include common ojects between hostboot and runtime hostboot
-include ../ipmi.mk
-
-OBJS += rt_ipmirp.o
-
-SUBDIRS += test.d
-
-VPATH += ..
-include $(ROOTPATH)/config.mk
-
diff --git a/src/usr/ipmi/runtime/rt_ipmirp.C b/src/usr/ipmi/runtime/rt_ipmirp.C
deleted file mode 100644
index 07d099f84..000000000
--- a/src/usr/ipmi/runtime/rt_ipmirp.C
+++ /dev/null
@@ -1,190 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/runtime/rt_ipmirp.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @file rt_ipmirp.C
- * @brief IPMI resource provider definition for runtime
- */
-
-#include "../ipmirp.H"
-#include "../ipmidd.H"
-#include <ipmi/ipmi_reasoncodes.H>
-#include <ipmi/ipmiif.H>
-
-#include <config.h>
-#include <sys/task.h>
-#include <initservice/taskargs.H>
-#include <initservice/initserviceif.H>
-#include <sys/vfs.h>
-
-#include <targeting/common/commontargeting.H>
-#include <kernel/ipc.H>
-#include <arch/ppc.H>
-#include <errl/errlmanager.H>
-#include <sys/time.h>
-#include <sys/misc.h>
-#include <errno.h>
-#include <runtime/interface.h>
-
-trace_desc_t * g_trac_ipmi;
-TRAC_INIT(&g_trac_ipmi, IPMI_COMP_NAME, 6*KILOBYTE, TRACE::BUFFER_SLOW);
-
-#define IPMI_TRAC(printf_string,args...) \
- TRACFCOMP(g_trac_ipmi,"rt: " printf_string,##args)
-
-namespace IPMI
-{
- static size_t g_max_buffer = 0;
- size_t max_buffer(void)
- {
- if (g_max_buffer == 0)
- {
- TARGETING::Target * sys = NULL;
- TARGETING::targetService().getTopLevelTarget( sys );
- if (sys)
- {
- g_max_buffer = sys->getAttr
- <TARGETING::ATTR_IPMI_MAX_BUFFER_SIZE>();
- IPMI_TRAC( INFO_MRK"getAttr(IPMI_MAX_BUFFER_SIZE) = %d",
- g_max_buffer);
- }
- else
- {
- IPMI_TRAC( ERR_MRK"IPMI_MAX_BUFFER_SIZE not available" );
- }
- }
- return g_max_buffer;
- }
-
- ///
- /// @brief Synchronus message send
- ///
- errlHndl_t sendrecv(const IPMI::command_t& i_cmd,
- IPMI::completion_code& o_completion_code,
- size_t& io_len, uint8_t*& io_data)
- {
- errlHndl_t err = NULL;
- int rc = 0;
-
- // if the buffer is too large this is a programming error.
- assert(io_len <= max_buffer());
-
- uint8_t netfn = i_cmd.first >> 2; //remove embedded LUN
- IPMI_TRAC("calling sync %x:%x len=%d",
- netfn, i_cmd.second, io_len);
-
- if(g_hostInterfaces && g_hostInterfaces->ipmi_msg)
- {
- size_t l_len = max_buffer(); // max size the BMC can return
- uint8_t *l_data = new uint8_t[l_len];
-
- rc = g_hostInterfaces->ipmi_msg(
- netfn, i_cmd.second,
- io_data, io_len,
- l_data, &l_len);
-
- if(rc)
- {
- IPMI_TRAC(ERR_MRK
- "Failed sending ipmi msg (%x:%x) to bmc rc: %d. ",
- i_cmd.first, i_cmd.second, rc);
-
- /*@
- * @errortype ERRL_SEV_UNRECOVERABLE
- * @moduleid IPMI::MOD_IPMIRT
- * @reasoncode IPMI::RC_INVALID_SENDRECV
- * @userdata1[0:31] rc from ipmi_msg()
- * @userdata1[32:46] netfn of failing msg
- * @userdata1[47:63] cmd of failing msg
- * @userdata2 length of failing msg
- * @devdesc ipmi_msg() failed
- * @custdesc Firmware error
- */
- err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- IPMI::MOD_IPMIRT,
- IPMI::RC_INVALID_SENDRECV,
- TWO_UINT32_TO_UINT64(rc,
- TWO_UINT16_TO_UINT32(netfn, i_cmd.second)),
- io_len,
- true);
- err->collectTrace(IPMI_COMP_NAME);
- delete[] io_data;
- io_data = NULL;
- io_len = 0;
- }
- else
- {
- // clean up the memory for the caller
- o_completion_code =
- static_cast<IPMI::completion_code>(l_data[0]);
-
- // now need to create the buffer to return
- io_len = l_len - 1; // get rid of the completion_code
- delete[] io_data;
- io_data = new uint8_t[io_len];
- memcpy(io_data, &l_data[1], io_len); // data after CC
- }
- delete[] l_data;
- }
- else
- {
- IPMI_TRAC(ERR_MRK
- "Host interfaces not initialized; ipmi msg not sent. ");
- }
-
- return err;
- } // sendrecv
-
- /*
- * @brief Asynchronus message send
- *
- * @param[in] i_cmd, the command we're sending
- * @param[in] i_len, the length of the data
- * @param[in] i_data, the data we're sending
- * @param[in] i_type, the type of message we're sending
- *
- */
- errlHndl_t send(const IPMI::command_t& i_cmd,
- size_t i_len, uint8_t* i_data,
- IPMI::message_type i_type)
- {
- IPMI::completion_code l_cc = IPMI::CC_UNKBAD;
-
- // We are calling a synchronous send in an asynchronous function
- // This is needed to enable asynchronous message sending before
- // runtime. A message should be synchronous during runtime, but
- // by ignoring the cc returned and clearing the data, we're making
- // a synchronous function "asynchronous".
- errlHndl_t l_err = sendrecv(i_cmd,l_cc,i_len,i_data);
-
- if(i_data != NULL)
- {
- delete i_data;
- }
-
- return l_err;
- }
-
-};
diff --git a/src/usr/ipmi/runtime/test/makefile b/src/usr/ipmi/runtime/test/makefile
deleted file mode 100644
index a12933112..000000000
--- a/src/usr/ipmi/runtime/test/makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/usr/ipmi/runtime/test/makefile $
-#
-# OpenPOWER HostBoot Project
-#
-# Contributors Listed Below - COPYRIGHT 2015
-# [+] International Business Machines Corp.
-#
-#
-# 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.
-#
-# IBM_PROLOG_END_TAG
-HOSTBOOT_RUNTIME = 1
-ROOTPATH = ../../../../..
-
-MODULE = testipmi_rt
-TESTS = *.H
-
-include ${ROOTPATH}/config.mk
diff --git a/src/usr/ipmi/runtime/test/rt_ipmitest.H b/src/usr/ipmi/runtime/test/rt_ipmitest.H
deleted file mode 100644
index b3a252e31..000000000
--- a/src/usr/ipmi/runtime/test/rt_ipmitest.H
+++ /dev/null
@@ -1,102 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/ipmi/runtime/test/rt_ipmitest.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* 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. */
-/* */
-/* IBM_PROLOG_END_TAG */
-#ifndef __RT_IPMITEST_H
-#define __RT_IPMITEST_H
-
-/**
- * @file ipmitest.H
- *
- * @brief Test case for IPMI messages
-*/
-
-#include <cxxtest/TestSuite.H>
-
-#include "../../../trace/entry.H"
-
-#include <ipmi/ipmiif.H>
-#include <ipmi/ipmisensor.H>
-
-
-class RT_IpmiTest: public CxxTest::TestSuite
-{
-public:
-
-
- /**
- * @brief call sendrecv directly
- */
- void testIpmi1(void)
- {
- do
- {
- IPMI::completion_code cc = IPMI::CC_UNKBAD;
- size_t len = 0;
- uint8_t* data = NULL;
- errlHndl_t err = IPMI::sendrecv(IPMI::get_capabilities(), cc, len, data);
-
- TS_WARN("testIpmi1: cc x%x, len %d", cc, len);
-
- if ( err != NULL )
- {
- TS_FAIL("testIpmi1: get_capabilities() failed");
- break;
- }
- if (cc != IPMI::CC_OK)
- {
- TS_FAIL("testIpmi1: get_capabilities() failed with cc 0x%x", cc);
- break;
- }
- if (len != 5)
- {
- TS_FAIL("testIpmi1: get_capabilities() returned len %d instead of 5",
- len);
- break;
- }
-
- TS_WARN("testIpmi1: get_capabilities x%x, x%x x%x x%x x%x",
- data[0], data[1], data[2], data[3], data[4]);
-
- }
- while(0);
- }
-
- /**
- * @brief call IPMI::sensor function
- */
- void testIpmi2(void)
- {
- do
- {
- uint8_t l_sensorNumber = SENSOR::getFaultSensorNumber(
- TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL);
-
- TS_WARN("testIpmi2: getFaultSensorNumber x%x",
- l_sensorNumber);
- }
- while(0);
- }
-};
-
-#endif
OpenPOWER on IntegriCloud