1b891a576SVishwanatha Subbanna #include "config.h"
20b02be92SPatrick Venture
346470a38SPatrick Venture #include "systemintfcmds.hpp"
40b02be92SPatrick Venture
53eb117a3SVishwanatha Subbanna #include "host-cmd-manager.hpp"
612866370SAndrew Geissler #include "host-interface.hpp"
79e5232e5STom
8194375f2SWilliam A. Kennington III #include <ipmid-host/cmd.hpp>
9240b186cSVernon Mauery #include <ipmid/api.hpp>
10e4aa6545SVernon Mauery #include <nlohmann/json.hpp>
119cd6d9a0SGeorge Liu #include <phosphor-logging/lg2.hpp>
129e5232e5STom
13fbc6c9d7SPatrick Williams #include <cstring>
14e4aa6545SVernon Mauery #include <fstream>
15fbc6c9d7SPatrick Williams
16*5087b075SGeorge Liu void registerNetFnAppFunctions() __attribute__((constructor));
179e5232e5STom
18523e2d1bSWilly Tu using namespace sdbusplus::server::xyz::openbmc_project::control;
1912866370SAndrew Geissler
203eb117a3SVishwanatha Subbanna // For accessing Host command manager
213eb117a3SVishwanatha Subbanna using cmdManagerPtr = std::unique_ptr<phosphor::host::command::Manager>;
223eb117a3SVishwanatha Subbanna extern cmdManagerPtr& ipmid_get_host_cmd_manager();
2312866370SAndrew Geissler
2412866370SAndrew Geissler //-------------------------------------------------------------------
2512866370SAndrew Geissler // Called by Host post response from Get_Message_Flags
2612866370SAndrew Geissler //-------------------------------------------------------------------
27e4aa6545SVernon Mauery ipmi::RspType<uint16_t, // id
28e4aa6545SVernon Mauery uint8_t, // type
29e4aa6545SVernon Mauery uint24_t, // manuf_id
30e4aa6545SVernon Mauery uint32_t, // timestamp
31e4aa6545SVernon Mauery uint8_t, // netfun
32e4aa6545SVernon Mauery uint8_t, // cmd
33e4aa6545SVernon Mauery std::array<uint8_t, 4> // data
34e4aa6545SVernon Mauery >
ipmiAppReadEventBuffer(ipmi::Context::ptr & ctx)35e4aa6545SVernon Mauery ipmiAppReadEventBuffer(ipmi::Context::ptr& ctx)
3612866370SAndrew Geissler {
37e4aa6545SVernon Mauery // require this to be limited to system interface
38e4aa6545SVernon Mauery if (ctx->channel != ipmi::channelSystemIface)
39e4aa6545SVernon Mauery {
40e4aa6545SVernon Mauery return ipmi::responseInvalidCommand();
41e4aa6545SVernon Mauery }
4212866370SAndrew Geissler
43e4aa6545SVernon Mauery constexpr uint16_t selOemId = 0x5555;
44e4aa6545SVernon Mauery constexpr uint8_t selRecordTypeOem = 0xc0;
4512866370SAndrew Geissler
46e4aa6545SVernon Mauery // read manufacturer ID from dev_id file
47e4aa6545SVernon Mauery static uint24_t manufId{};
48e4aa6545SVernon Mauery if (!manufId)
49e4aa6545SVernon Mauery {
50e4aa6545SVernon Mauery const char* filename = "/usr/share/ipmi-providers/dev_id.json";
51e4aa6545SVernon Mauery std::ifstream devIdFile(filename);
52e4aa6545SVernon Mauery if (devIdFile.is_open())
53e4aa6545SVernon Mauery {
54e4aa6545SVernon Mauery auto data = nlohmann::json::parse(devIdFile, nullptr, false);
55e4aa6545SVernon Mauery if (!data.is_discarded())
56e4aa6545SVernon Mauery {
57e4aa6545SVernon Mauery manufId = data.value("manuf_id", 0);
58e4aa6545SVernon Mauery }
59e4aa6545SVernon Mauery }
60e4aa6545SVernon Mauery }
619e5232e5STom
62e4aa6545SVernon Mauery constexpr uint32_t timestamp{0};
639e5232e5STom
649e5232e5STom // per IPMI spec NetFuntion for OEM
65e4aa6545SVernon Mauery constexpr uint8_t netfun = 0x3a;
669e5232e5STom
673eb117a3SVishwanatha Subbanna // Read from the Command Manager queue. What gets returned is a
683eb117a3SVishwanatha Subbanna // pair of <command, data> that can be directly used here
69e4aa6545SVernon Mauery const auto& [cmd, data0] = ipmid_get_host_cmd_manager()->getNextCommand();
70e4aa6545SVernon Mauery constexpr uint8_t dataUnused = 0xff;
719e5232e5STom
72e4aa6545SVernon Mauery return ipmi::responseSuccess(
73e4aa6545SVernon Mauery selOemId, selRecordTypeOem, manufId, timestamp, netfun, cmd,
74e4aa6545SVernon Mauery std::to_array<uint8_t>({data0, dataUnused, dataUnused, dataUnused}));
759e5232e5STom }
769e5232e5STom
779e5232e5STom //---------------------------------------------------------------------
789e5232e5STom // Called by Host on seeing a SMS_ATN bit set. Return a hardcoded
79414d2f7bSXP Chen // value of 0x0 to indicate Event Message Buffer is not supported
809e5232e5STom //-------------------------------------------------------------------
ipmiAppGetMessageFlags()81461f4645SAndrew Geissler ipmi::RspType<uint8_t> ipmiAppGetMessageFlags()
829e5232e5STom {
839e5232e5STom // From IPMI spec V2.0 for Get Message Flags Command :
849e5232e5STom // bit:[1] from LSB : 1b = Event Message Buffer Full.
859e5232e5STom // Return as 0 if Event Message Buffer is not supported,
869e5232e5STom // or when the Event Message buffer is disabled.
87461f4645SAndrew Geissler // This path is used to communicate messages to the host
88461f4645SAndrew Geissler // from within the phosphor::host::command::Manager
89414d2f7bSXP Chen constexpr uint8_t setEventMsgBufferNotSupported = 0x0;
90414d2f7bSXP Chen return ipmi::responseSuccess(setEventMsgBufferNotSupported);
919e5232e5STom }
929e5232e5STom
935aa26937SYong Li ipmi::RspType<bool, // Receive Message Queue Interrupt Enabled
945aa26937SYong Li bool, // Event Message Buffer Full Interrupt Enabled
955aa26937SYong Li bool, // Event Message Buffer Enabled
965aa26937SYong Li bool, // System Event Logging Enabled
975aa26937SYong Li uint1_t, // Reserved
985aa26937SYong Li bool, // OEM 0 enabled
995aa26937SYong Li bool, // OEM 1 enabled
1005aa26937SYong Li bool // OEM 2 enabled
1015aa26937SYong Li >
ipmiAppGetBMCGlobalEnable()1025aa26937SYong Li ipmiAppGetBMCGlobalEnable()
10330206dbaSJia, Chunhui {
1045aa26937SYong Li return ipmi::responseSuccess(true, false, false, true, 0, false, false,
1055aa26937SYong Li false);
10630206dbaSJia, Chunhui }
10730206dbaSJia, Chunhui
ipmiAppSetBMCGlobalEnable(ipmi::Context::ptr ctx,bool receiveMessageQueueInterruptEnabled,bool eventMessageBufferFullInterruptEnabled,bool eventMessageBufferEnabled,bool systemEventLogEnable,uint1_t reserved,bool OEM0Enabled,bool OEM1Enabled,bool OEM2Enabled)108ecd7bb98SYong Li ipmi::RspType<> ipmiAppSetBMCGlobalEnable(
109ecd7bb98SYong Li ipmi::Context::ptr ctx, bool receiveMessageQueueInterruptEnabled,
110ecd7bb98SYong Li bool eventMessageBufferFullInterruptEnabled, bool eventMessageBufferEnabled,
111ecd7bb98SYong Li bool systemEventLogEnable, uint1_t reserved, bool OEM0Enabled,
112ecd7bb98SYong Li bool OEM1Enabled, bool OEM2Enabled)
1139e5232e5STom {
114a249a082SYong Li ipmi::ChannelInfo chInfo;
115a249a082SYong Li
116a249a082SYong Li if (ipmi::getChannelInfo(ctx->channel, chInfo) != ipmi::ccSuccess)
117a249a082SYong Li {
1189cd6d9a0SGeorge Liu lg2::error("Failed to get Channel Info, channel={CHANNEL}", "CHANNEL",
1199cd6d9a0SGeorge Liu ctx->channel);
120a249a082SYong Li return ipmi::responseUnspecifiedError();
121a249a082SYong Li }
122a249a082SYong Li
123a249a082SYong Li if (chInfo.mediumType !=
124a249a082SYong Li static_cast<uint8_t>(ipmi::EChannelMediumType::systemInterface))
125a249a082SYong Li {
1269cd6d9a0SGeorge Liu lg2::error("Error - supported only in system interface");
127a249a082SYong Li return ipmi::responseCommandNotAvailable();
128a249a082SYong Li }
129a249a082SYong Li
13030206dbaSJia, Chunhui // Recv Message Queue and SEL are enabled by default.
13130206dbaSJia, Chunhui // Event Message buffer are disabled by default (not supported).
13230206dbaSJia, Chunhui // Any request that try to change the mask will be rejected
133ecd7bb98SYong Li if (!receiveMessageQueueInterruptEnabled || !systemEventLogEnable ||
134ecd7bb98SYong Li eventMessageBufferFullInterruptEnabled || eventMessageBufferEnabled ||
135ecd7bb98SYong Li OEM0Enabled || OEM1Enabled || OEM2Enabled || reserved)
13630206dbaSJia, Chunhui {
137ecd7bb98SYong Li return ipmi::responseInvalidFieldRequest();
13830206dbaSJia, Chunhui }
139ecd7bb98SYong Li
140ecd7bb98SYong Li return ipmi::responseSuccess();
1419e5232e5STom }
1429e5232e5STom
1430b02be92SPatrick Venture namespace
1440b02be92SPatrick Venture {
14512c2db79SLei YU // Static storage to keep the object alive during process life
1463eb117a3SVishwanatha Subbanna std::unique_ptr<phosphor::host::command::Host> host
1473eb117a3SVishwanatha Subbanna __attribute__((init_priority(101)));
1485d82f474SPatrick Williams std::unique_ptr<sdbusplus::server::manager_t> objManager
1493eb117a3SVishwanatha Subbanna __attribute__((init_priority(101)));
1500b02be92SPatrick Venture } // namespace
15112866370SAndrew Geissler
registerNetFnAppFunctions()152*5087b075SGeorge Liu void registerNetFnAppFunctions()
1539e5232e5STom {
1549e5232e5STom // <Read Event Message Buffer>
155e4aa6545SVernon Mauery ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
156e4aa6545SVernon Mauery ipmi::app::cmdReadEventMessageBuffer,
157e4aa6545SVernon Mauery ipmi::Privilege::Admin, ipmiAppReadEventBuffer);
1589e5232e5STom
1599e5232e5STom // <Set BMC Global Enables>
160ecd7bb98SYong Li ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
161ecd7bb98SYong Li ipmi::app::cmdSetBmcGlobalEnables,
162ecd7bb98SYong Li ipmi::Privilege::Admin, ipmiAppSetBMCGlobalEnable);
1639e5232e5STom
16430206dbaSJia, Chunhui // <Get BMC Global Enables>
1655aa26937SYong Li ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
1665aa26937SYong Li ipmi::app::cmdGetBmcGlobalEnables,
1675aa26937SYong Li ipmi::Privilege::User, ipmiAppGetBMCGlobalEnable);
16830206dbaSJia, Chunhui
1699e5232e5STom // <Get Message Flags>
170461f4645SAndrew Geissler ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
171461f4645SAndrew Geissler ipmi::app::cmdGetMessageFlags, ipmi::Privilege::Admin,
172461f4645SAndrew Geissler ipmiAppGetMessageFlags);
1739e5232e5STom
17412866370SAndrew Geissler // Create new xyz.openbmc_project.host object on the bus
1753eb117a3SVishwanatha Subbanna auto objPath = std::string{CONTROL_HOST_OBJ_MGR} + '/' + HOST_NAME + '0';
17612866370SAndrew Geissler
17720ff333dSVernon Mauery std::unique_ptr<sdbusplus::asio::connection>& sdbusp =
17820ff333dSVernon Mauery ipmid_get_sdbus_plus_handler();
17912866370SAndrew Geissler
180240b186cSVernon Mauery // Add sdbusplus ObjectManager.
1815d82f474SPatrick Williams objManager = std::make_unique<sdbusplus::server::manager_t>(
182240b186cSVernon Mauery *sdbusp, CONTROL_HOST_OBJ_MGR);
183240b186cSVernon Mauery
1841318a5edSPatrick Williams host = std::make_unique<phosphor::host::command::Host>(
1851318a5edSPatrick Williams *sdbusp, objPath.c_str());
186240b186cSVernon Mauery sdbusp->request_name(CONTROL_HOST_BUSNAME);
18712866370SAndrew Geissler
1889e5232e5STom return;
1899e5232e5STom }
190