1e7d23d0eSVijay Khemka /*
2e7d23d0eSVijay Khemka * Copyright (c) 2018 Intel Corporation.
3e7d23d0eSVijay Khemka * Copyright (c) 2018-present Facebook.
4e7d23d0eSVijay Khemka *
5e7d23d0eSVijay Khemka * Licensed under the Apache License, Version 2.0 (the "License");
6e7d23d0eSVijay Khemka * you may not use this file except in compliance with the License.
7e7d23d0eSVijay Khemka * You may obtain a copy of the License at
8e7d23d0eSVijay Khemka *
9e7d23d0eSVijay Khemka * http://www.apache.org/licenses/LICENSE-2.0
10e7d23d0eSVijay Khemka *
11e7d23d0eSVijay Khemka * Unless required by applicable law or agreed to in writing, software
12e7d23d0eSVijay Khemka * distributed under the License is distributed on an "AS IS" BASIS,
13e7d23d0eSVijay Khemka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14e7d23d0eSVijay Khemka * See the License for the specific language governing permissions and
15e7d23d0eSVijay Khemka * limitations under the License.
16e7d23d0eSVijay Khemka */
17e7d23d0eSVijay Khemka
18e7d23d0eSVijay Khemka #include "xyz/openbmc_project/Common/error.hpp"
19e7d23d0eSVijay Khemka
2099d42b6eSCosmo Chou #include <boost/crc.hpp>
212405ae98SPatrick Williams #include <commandutils.hpp>
222405ae98SPatrick Williams #include <ipmid/api-types.hpp>
2363c99be4SVijay Khemka #include <ipmid/api.hpp>
241b6fae3fSVijay Khemka #include <ipmid/utils.hpp>
2563c99be4SVijay Khemka #include <nlohmann/json.hpp>
2663c99be4SVijay Khemka #include <oemcommands.hpp>
27e7d23d0eSVijay Khemka #include <phosphor-logging/log.hpp>
28e7d23d0eSVijay Khemka #include <sdbusplus/bus.hpp>
292405ae98SPatrick Williams #include <xyz/openbmc_project/Control/Boot/Mode/server.hpp>
302405ae98SPatrick Williams #include <xyz/openbmc_project/Control/Boot/Source/server.hpp>
312405ae98SPatrick Williams #include <xyz/openbmc_project/Control/Boot/Type/server.hpp>
325f8e3435SManikandan Elumalai
3363c99be4SVijay Khemka #include <array>
3463c99be4SVijay Khemka #include <cstring>
3563c99be4SVijay Khemka #include <fstream>
3663c99be4SVijay Khemka #include <iomanip>
3763c99be4SVijay Khemka #include <iostream>
382405ae98SPatrick Williams #include <regex>
3963c99be4SVijay Khemka #include <sstream>
40e7d23d0eSVijay Khemka #include <string>
41e7d23d0eSVijay Khemka #include <vector>
42e7d23d0eSVijay Khemka
43e7d23d0eSVijay Khemka #define SIZE_IANA_ID 3
44e7d23d0eSVijay Khemka
45e7d23d0eSVijay Khemka namespace ipmi
46e7d23d0eSVijay Khemka {
47a7231893SVijay Khemka
48a7231893SVijay Khemka using namespace phosphor::logging;
49a7231893SVijay Khemka
50e1ff81faSKarthikeyan Pasupathi void getSelectorPosition(size_t& position);
51e7d23d0eSVijay Khemka static void registerOEMFunctions() __attribute__((constructor));
52cd315e07SPatrick Williams sdbusplus::bus_t dbus(ipmid_get_sd_bus_connection()); // from ipmid/api.h
53e7d23d0eSVijay Khemka static constexpr size_t maxFRUStringLength = 0x3F;
545f8e3435SManikandan Elumalai constexpr uint8_t cmdSetSystemGuid = 0xEF;
55e7d23d0eSVijay Khemka
5610ff3d86SKarthikeyan Pasupathi constexpr uint8_t cmdSetQDimmInfo = 0x12;
5710ff3d86SKarthikeyan Pasupathi constexpr uint8_t cmdGetQDimmInfo = 0x13;
5810ff3d86SKarthikeyan Pasupathi
597ab87bbbSCosmo Chou constexpr ipmi_ret_t ccInvalidParam = 0x80;
607ab87bbbSCosmo Chou
61cc0d6d92SVijay Khemka int plat_udbg_get_post_desc(uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t*,
62cc0d6d92SVijay Khemka uint8_t*);
6338183d66SVijay Khemka int plat_udbg_get_gpio_desc(uint8_t, uint8_t*, uint8_t*, uint8_t*, uint8_t*,
6438183d66SVijay Khemka uint8_t*);
655e589481SPatrick Williams int plat_udbg_get_frame_data(uint8_t, uint8_t, uint8_t*, uint8_t*, uint8_t*);
66e7d23d0eSVijay Khemka ipmi_ret_t plat_udbg_control_panel(uint8_t, uint8_t, uint8_t, uint8_t*,
67e7d23d0eSVijay Khemka uint8_t*);
68dd14c0f7SVijay Khemka int sendMeCmd(uint8_t, uint8_t, std::vector<uint8_t>&, std::vector<uint8_t>&);
69dd14c0f7SVijay Khemka
705f8e3435SManikandan Elumalai int sendBicCmd(uint8_t, uint8_t, uint8_t, std::vector<uint8_t>&,
715f8e3435SManikandan Elumalai std::vector<uint8_t>&);
725f8e3435SManikandan Elumalai
73feaa9811SVijay Khemka nlohmann::json oemData __attribute__((init_priority(101)));
741b6fae3fSVijay Khemka
7599d42b6eSCosmo Chou constexpr const char* certPath = "/mnt/data/host/bios-rootcert";
7699d42b6eSCosmo Chou
77f2246ce8SVijay Khemka static constexpr size_t GUID_SIZE = 16;
78f2246ce8SVijay Khemka // TODO Make offset and location runtime configurable to ensure we
79f2246ce8SVijay Khemka // can make each define their own locations.
80f2246ce8SVijay Khemka static constexpr off_t OFFSET_SYS_GUID = 0x17F0;
81f2246ce8SVijay Khemka static constexpr const char* FRU_EEPROM = "/sys/bus/i2c/devices/6-0054/eeprom";
827bb4592aSDelphine CC Chiu void flushOemData();
83f2246ce8SVijay Khemka
841b6fae3fSVijay Khemka enum class LanParam : uint8_t
851b6fae3fSVijay Khemka {
861b6fae3fSVijay Khemka INPROGRESS = 0,
871b6fae3fSVijay Khemka AUTHSUPPORT = 1,
881b6fae3fSVijay Khemka AUTHENABLES = 2,
891b6fae3fSVijay Khemka IP = 3,
901b6fae3fSVijay Khemka IPSRC = 4,
911b6fae3fSVijay Khemka MAC = 5,
921b6fae3fSVijay Khemka SUBNET = 6,
931b6fae3fSVijay Khemka GATEWAY = 12,
941b6fae3fSVijay Khemka VLAN = 20,
951b6fae3fSVijay Khemka CIPHER_SUITE_COUNT = 22,
961b6fae3fSVijay Khemka CIPHER_SUITE_ENTRIES = 23,
971b6fae3fSVijay Khemka IPV6 = 59,
981b6fae3fSVijay Khemka };
991b6fae3fSVijay Khemka
100a7231893SVijay Khemka namespace network
101a7231893SVijay Khemka {
102a7231893SVijay Khemka
103a7231893SVijay Khemka constexpr auto ROOT = "/xyz/openbmc_project/network";
104a7231893SVijay Khemka constexpr auto SERVICE = "xyz.openbmc_project.Network";
105a7231893SVijay Khemka constexpr auto IPV4_TYPE = "ipv4";
106a7231893SVijay Khemka constexpr auto IPV6_TYPE = "ipv6";
107a7231893SVijay Khemka constexpr auto IPV4_PREFIX = "169.254";
108a7231893SVijay Khemka constexpr auto IPV6_PREFIX = "fe80";
109a7231893SVijay Khemka constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
110a7231893SVijay Khemka constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
1118d1a81e8SPotin Lai constexpr auto IPV4_PROTOCOL = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
1128d1a81e8SPotin Lai constexpr auto IPV6_PROTOCOL = "xyz.openbmc_project.Network.IP.Protocol.IPv6";
113a7231893SVijay Khemka
isLinkLocalIP(const std::string & address)114a7231893SVijay Khemka bool isLinkLocalIP(const std::string& address)
115a7231893SVijay Khemka {
116a7231893SVijay Khemka return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0;
117a7231893SVijay Khemka }
118a7231893SVijay Khemka
getIPObject(sdbusplus::bus_t & bus,const std::string & interface,const std::string & serviceRoot,const std::string & protocol,const std::string & ethdev)119cd315e07SPatrick Williams DbusObjectInfo getIPObject(sdbusplus::bus_t& bus, const std::string& interface,
120a7231893SVijay Khemka const std::string& serviceRoot,
1218d1a81e8SPotin Lai const std::string& protocol,
1228d1a81e8SPotin Lai const std::string& ethdev)
123a7231893SVijay Khemka {
1248d1a81e8SPotin Lai auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, ethdev);
125a7231893SVijay Khemka
126a7231893SVijay Khemka if (objectTree.empty())
127a7231893SVijay Khemka {
128a7231893SVijay Khemka log<level::ERR>("No Object has implemented the IP interface",
129a7231893SVijay Khemka entry("INTERFACE=%s", interface.c_str()));
130a7231893SVijay Khemka }
131a7231893SVijay Khemka
132a7231893SVijay Khemka DbusObjectInfo objectInfo;
133a7231893SVijay Khemka
134a7231893SVijay Khemka for (auto& object : objectTree)
135a7231893SVijay Khemka {
136010dee04SPatrick Williams auto variant =
137010dee04SPatrick Williams ipmi::getDbusProperty(bus, object.second.begin()->first,
138010dee04SPatrick Williams object.first, IP_INTERFACE, "Type");
1398d1a81e8SPotin Lai if (std::get<std::string>(variant) != protocol)
1408d1a81e8SPotin Lai {
1418d1a81e8SPotin Lai continue;
1428d1a81e8SPotin Lai }
1438d1a81e8SPotin Lai
1448d1a81e8SPotin Lai variant = ipmi::getDbusProperty(bus, object.second.begin()->first,
145a7231893SVijay Khemka object.first, IP_INTERFACE, "Address");
146a7231893SVijay Khemka
147a7231893SVijay Khemka objectInfo = std::make_pair(object.first, object.second.begin()->first);
148a7231893SVijay Khemka
149a7231893SVijay Khemka // if LinkLocalIP found look for Non-LinkLocalIP
150a7231893SVijay Khemka if (isLinkLocalIP(std::get<std::string>(variant)))
151a7231893SVijay Khemka {
152a7231893SVijay Khemka continue;
153a7231893SVijay Khemka }
154a7231893SVijay Khemka else
155a7231893SVijay Khemka {
156a7231893SVijay Khemka break;
157a7231893SVijay Khemka }
158a7231893SVijay Khemka }
159a7231893SVijay Khemka return objectInfo;
160a7231893SVijay Khemka }
161a7231893SVijay Khemka
162a7231893SVijay Khemka } // namespace network
163a7231893SVijay Khemka
164f0cf6658SJayashree-D namespace boot
165f0cf6658SJayashree-D {
16677ee489fSJayashree Dhanapal using BootSource =
16777ee489fSJayashree Dhanapal sdbusplus::xyz::openbmc_project::Control::Boot::server::Source::Sources;
16877ee489fSJayashree Dhanapal using BootMode =
16977ee489fSJayashree Dhanapal sdbusplus::xyz::openbmc_project::Control::Boot::server::Mode::Modes;
17077ee489fSJayashree Dhanapal using BootType =
17177ee489fSJayashree Dhanapal sdbusplus::xyz::openbmc_project::Control::Boot::server::Type::Types;
172f0cf6658SJayashree-D
173f0cf6658SJayashree-D using IpmiValue = uint8_t;
174f0cf6658SJayashree-D
17577ee489fSJayashree Dhanapal std::map<IpmiValue, BootSource> sourceIpmiToDbus = {
17677ee489fSJayashree Dhanapal {0x0f, BootSource::Default}, {0x00, BootSource::RemovableMedia},
17777ee489fSJayashree Dhanapal {0x01, BootSource::Network}, {0x02, BootSource::Disk},
1787bb4592aSDelphine CC Chiu {0x03, BootSource::ExternalMedia}, {0x04, BootSource::RemovableMedia},
1797bb4592aSDelphine CC Chiu {0x09, BootSource::Network}};
180f0cf6658SJayashree-D
181c0f918b5SDelphine CC Chiu std::map<IpmiValue, BootMode> modeIpmiToDbus = {{0x04, BootMode::Setup},
18277ee489fSJayashree Dhanapal {0x00, BootMode::Regular}};
183f0cf6658SJayashree-D
18477ee489fSJayashree Dhanapal std::map<IpmiValue, BootType> typeIpmiToDbus = {{0x00, BootType::Legacy},
18577ee489fSJayashree Dhanapal {0x01, BootType::EFI}};
186778147daSJayashree Dhanapal
18777ee489fSJayashree Dhanapal std::map<std::optional<BootSource>, IpmiValue> sourceDbusToIpmi = {
18877ee489fSJayashree Dhanapal {BootSource::Default, 0x0f},
18977ee489fSJayashree Dhanapal {BootSource::RemovableMedia, 0x00},
19077ee489fSJayashree Dhanapal {BootSource::Network, 0x01},
19177ee489fSJayashree Dhanapal {BootSource::Disk, 0x02},
19277ee489fSJayashree Dhanapal {BootSource::ExternalMedia, 0x03}};
193f0cf6658SJayashree-D
19477ee489fSJayashree Dhanapal std::map<std::optional<BootMode>, IpmiValue> modeDbusToIpmi = {
195c0f918b5SDelphine CC Chiu {BootMode::Setup, 0x04}, {BootMode::Regular, 0x00}};
196f0cf6658SJayashree-D
19777ee489fSJayashree Dhanapal std::map<std::optional<BootType>, IpmiValue> typeDbusToIpmi = {
19877ee489fSJayashree Dhanapal {BootType::Legacy, 0x00}, {BootType::EFI, 0x01}};
199778147daSJayashree Dhanapal
200c0f918b5SDelphine CC Chiu static constexpr auto bootEnableIntf = "xyz.openbmc_project.Object.Enable";
201f0cf6658SJayashree-D static constexpr auto bootModeIntf = "xyz.openbmc_project.Control.Boot.Mode";
202f0cf6658SJayashree-D static constexpr auto bootSourceIntf =
203f0cf6658SJayashree-D "xyz.openbmc_project.Control.Boot.Source";
204778147daSJayashree Dhanapal static constexpr auto bootTypeIntf = "xyz.openbmc_project.Control.Boot.Type";
205f0cf6658SJayashree-D static constexpr auto bootSourceProp = "BootSource";
206f0cf6658SJayashree-D static constexpr auto bootModeProp = "BootMode";
207778147daSJayashree Dhanapal static constexpr auto bootTypeProp = "BootType";
208c0f918b5SDelphine CC Chiu static constexpr auto bootEnableProp = "Enabled";
209f0cf6658SJayashree-D
objPath(size_t id)210f0cf6658SJayashree-D std::tuple<std::string, std::string> objPath(size_t id)
211f0cf6658SJayashree-D {
212f0cf6658SJayashree-D std::string hostName = "host" + std::to_string(id);
213010dee04SPatrick Williams std::string bootObjPath =
214010dee04SPatrick Williams "/xyz/openbmc_project/control/" + hostName + "/boot";
215f0cf6658SJayashree-D return std::make_tuple(std::move(bootObjPath), std::move(hostName));
216f0cf6658SJayashree-D }
217f0cf6658SJayashree-D
2187bb4592aSDelphine CC Chiu /* Helper functions to set boot order */
setBootOrder(std::string bootObjPath,const std::vector<uint8_t> & bootSeq,std::string bootOrderKey)2197bb4592aSDelphine CC Chiu void setBootOrder(std::string bootObjPath, const std::vector<uint8_t>& bootSeq,
2207bb4592aSDelphine CC Chiu std::string bootOrderKey)
2217bb4592aSDelphine CC Chiu {
2227bb4592aSDelphine CC Chiu if (bootSeq.size() != SIZE_BOOT_ORDER)
2237bb4592aSDelphine CC Chiu {
2247bb4592aSDelphine CC Chiu phosphor::logging::log<phosphor::logging::level::ERR>(
2257bb4592aSDelphine CC Chiu "Invalid Boot order length received");
2267bb4592aSDelphine CC Chiu return;
2277bb4592aSDelphine CC Chiu }
2287bb4592aSDelphine CC Chiu
2297bb4592aSDelphine CC Chiu std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
2307bb4592aSDelphine CC Chiu
2317bb4592aSDelphine CC Chiu uint8_t mode = bootSeq.front();
2327bb4592aSDelphine CC Chiu
2337bb4592aSDelphine CC Chiu // SETTING BOOT MODE PROPERTY
2347bb4592aSDelphine CC Chiu uint8_t bootModeBit = mode & 0x04;
2357bb4592aSDelphine CC Chiu auto bootValue = ipmi::boot::modeIpmiToDbus.at(bootModeBit);
2367bb4592aSDelphine CC Chiu
2377bb4592aSDelphine CC Chiu std::string bootOption =
2387bb4592aSDelphine CC Chiu sdbusplus::message::convert_to_string<boot::BootMode>(bootValue);
2397bb4592aSDelphine CC Chiu
240010dee04SPatrick Williams std::string service =
241010dee04SPatrick Williams getService(*dbus, ipmi::boot::bootModeIntf, bootObjPath);
2427bb4592aSDelphine CC Chiu setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootModeIntf,
2437bb4592aSDelphine CC Chiu ipmi::boot::bootModeProp, bootOption);
2447bb4592aSDelphine CC Chiu
2457bb4592aSDelphine CC Chiu // SETTING BOOT SOURCE PROPERTY
2467bb4592aSDelphine CC Chiu auto bootOrder = ipmi::boot::sourceIpmiToDbus.at(bootSeq.at(1));
2477bb4592aSDelphine CC Chiu std::string bootSource =
2487bb4592aSDelphine CC Chiu sdbusplus::message::convert_to_string<boot::BootSource>(bootOrder);
2497bb4592aSDelphine CC Chiu
2507bb4592aSDelphine CC Chiu service = getService(*dbus, ipmi::boot::bootSourceIntf, bootObjPath);
2517bb4592aSDelphine CC Chiu setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootSourceIntf,
2527bb4592aSDelphine CC Chiu ipmi::boot::bootSourceProp, bootSource);
2537bb4592aSDelphine CC Chiu
2547bb4592aSDelphine CC Chiu // SETTING BOOT TYPE PROPERTY
2557bb4592aSDelphine CC Chiu uint8_t bootTypeBit = mode & 0x01;
2567bb4592aSDelphine CC Chiu auto bootTypeVal = ipmi::boot::typeIpmiToDbus.at(bootTypeBit);
2577bb4592aSDelphine CC Chiu
2587bb4592aSDelphine CC Chiu std::string bootType =
2597bb4592aSDelphine CC Chiu sdbusplus::message::convert_to_string<boot::BootType>(bootTypeVal);
2607bb4592aSDelphine CC Chiu
2617bb4592aSDelphine CC Chiu service = getService(*dbus, ipmi::boot::bootTypeIntf, bootObjPath);
2627bb4592aSDelphine CC Chiu
2637bb4592aSDelphine CC Chiu setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootTypeIntf,
2647bb4592aSDelphine CC Chiu ipmi::boot::bootTypeProp, bootType);
2657bb4592aSDelphine CC Chiu
2667bb4592aSDelphine CC Chiu // Set the valid bit to boot enabled property
2677bb4592aSDelphine CC Chiu service = getService(*dbus, ipmi::boot::bootEnableIntf, bootObjPath);
2687bb4592aSDelphine CC Chiu
2697bb4592aSDelphine CC Chiu setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootEnableIntf,
2707bb4592aSDelphine CC Chiu ipmi::boot::bootEnableProp,
2717bb4592aSDelphine CC Chiu (mode & BOOT_MODE_BOOT_FLAG) ? true : false);
2727bb4592aSDelphine CC Chiu
2737bb4592aSDelphine CC Chiu nlohmann::json bootMode;
2747bb4592aSDelphine CC Chiu
2757bb4592aSDelphine CC Chiu bootMode["UEFI"] = (mode & BOOT_MODE_UEFI) ? true : false;
2767bb4592aSDelphine CC Chiu bootMode["CMOS_CLR"] = (mode & BOOT_MODE_CMOS_CLR) ? true : false;
2777bb4592aSDelphine CC Chiu bootMode["FORCE_BOOT"] = (mode & BOOT_MODE_FORCE_BOOT) ? true : false;
2787bb4592aSDelphine CC Chiu bootMode["BOOT_FLAG"] = (mode & BOOT_MODE_BOOT_FLAG) ? true : false;
2797bb4592aSDelphine CC Chiu oemData[bootOrderKey][KEY_BOOT_MODE] = bootMode;
2807bb4592aSDelphine CC Chiu
2817bb4592aSDelphine CC Chiu /* Initialize boot sequence array */
2827bb4592aSDelphine CC Chiu oemData[bootOrderKey][KEY_BOOT_SEQ] = {};
2837bb4592aSDelphine CC Chiu for (size_t i = 1; i < SIZE_BOOT_ORDER; i++)
2847bb4592aSDelphine CC Chiu {
2857bb4592aSDelphine CC Chiu if (bootSeq.at(i) >= BOOT_SEQ_ARRAY_SIZE)
2867bb4592aSDelphine CC Chiu oemData[bootOrderKey][KEY_BOOT_SEQ][i - 1] = "NA";
2877bb4592aSDelphine CC Chiu else
2887bb4592aSDelphine CC Chiu oemData[bootOrderKey][KEY_BOOT_SEQ][i - 1] =
2897bb4592aSDelphine CC Chiu bootSeqDefine[bootSeq.at(i)];
2907bb4592aSDelphine CC Chiu }
2917bb4592aSDelphine CC Chiu
2927bb4592aSDelphine CC Chiu flushOemData();
2937bb4592aSDelphine CC Chiu }
2947bb4592aSDelphine CC Chiu
getBootOrder(std::string bootObjPath,std::vector<uint8_t> & bootSeq,std::string hostName)2957bb4592aSDelphine CC Chiu void getBootOrder(std::string bootObjPath, std::vector<uint8_t>& bootSeq,
2967bb4592aSDelphine CC Chiu std::string hostName)
2977bb4592aSDelphine CC Chiu {
2987bb4592aSDelphine CC Chiu if (oemData.find(hostName) == oemData.end())
2997bb4592aSDelphine CC Chiu {
3007bb4592aSDelphine CC Chiu /* Return default boot order 0100090203ff */
3017bb4592aSDelphine CC Chiu bootSeq.push_back(BOOT_MODE_UEFI);
3027bb4592aSDelphine CC Chiu bootSeq.push_back(static_cast<uint8_t>(bootMap["USB_DEV"]));
3037bb4592aSDelphine CC Chiu bootSeq.push_back(static_cast<uint8_t>(bootMap["NET_IPV6"]));
3047bb4592aSDelphine CC Chiu bootSeq.push_back(static_cast<uint8_t>(bootMap["SATA_HDD"]));
3057bb4592aSDelphine CC Chiu bootSeq.push_back(static_cast<uint8_t>(bootMap["SATA_CD"]));
3067bb4592aSDelphine CC Chiu bootSeq.push_back(0xff);
3077bb4592aSDelphine CC Chiu
3087bb4592aSDelphine CC Chiu phosphor::logging::log<phosphor::logging::level::INFO>(
3097bb4592aSDelphine CC Chiu "Set default boot order");
3107bb4592aSDelphine CC Chiu setBootOrder(bootObjPath, bootSeq, hostName);
3117bb4592aSDelphine CC Chiu return;
3127bb4592aSDelphine CC Chiu }
3137bb4592aSDelphine CC Chiu
3147bb4592aSDelphine CC Chiu std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
3157bb4592aSDelphine CC Chiu
3167bb4592aSDelphine CC Chiu // GETTING PROPERTY OF MODE INTERFACE
3177bb4592aSDelphine CC Chiu
318010dee04SPatrick Williams std::string service =
319010dee04SPatrick Williams getService(*dbus, ipmi::boot::bootModeIntf, bootObjPath);
320010dee04SPatrick Williams Value variant =
321010dee04SPatrick Williams getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootModeIntf,
3227bb4592aSDelphine CC Chiu ipmi::boot::bootModeProp);
3237bb4592aSDelphine CC Chiu
3247bb4592aSDelphine CC Chiu auto bootMode = sdbusplus::message::convert_from_string<boot::BootMode>(
3257bb4592aSDelphine CC Chiu std::get<std::string>(variant));
3267bb4592aSDelphine CC Chiu
3277bb4592aSDelphine CC Chiu uint8_t bootOption = ipmi::boot::modeDbusToIpmi.at(bootMode);
3287bb4592aSDelphine CC Chiu
3297bb4592aSDelphine CC Chiu // GETTING PROPERTY OF TYPE INTERFACE
3307bb4592aSDelphine CC Chiu
3317bb4592aSDelphine CC Chiu service = getService(*dbus, ipmi::boot::bootTypeIntf, bootObjPath);
332010dee04SPatrick Williams variant =
333010dee04SPatrick Williams getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootTypeIntf,
3347bb4592aSDelphine CC Chiu ipmi::boot::bootTypeProp);
3357bb4592aSDelphine CC Chiu
3367bb4592aSDelphine CC Chiu auto bootType = sdbusplus::message::convert_from_string<boot::BootType>(
3377bb4592aSDelphine CC Chiu std::get<std::string>(variant));
3387bb4592aSDelphine CC Chiu
3397bb4592aSDelphine CC Chiu // Get the valid bit to boot enabled property
3407bb4592aSDelphine CC Chiu service = getService(*dbus, ipmi::boot::bootEnableIntf, bootObjPath);
341010dee04SPatrick Williams variant =
342010dee04SPatrick Williams getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootEnableIntf,
3437bb4592aSDelphine CC Chiu ipmi::boot::bootEnableProp);
3447bb4592aSDelphine CC Chiu
3457bb4592aSDelphine CC Chiu bool validFlag = std::get<bool>(variant);
3467bb4592aSDelphine CC Chiu
3477bb4592aSDelphine CC Chiu uint8_t bootTypeVal = ipmi::boot::typeDbusToIpmi.at(bootType);
3487bb4592aSDelphine CC Chiu
3497bb4592aSDelphine CC Chiu bootSeq.push_back(bootOption | bootTypeVal);
3507bb4592aSDelphine CC Chiu
3517bb4592aSDelphine CC Chiu if (validFlag)
3527bb4592aSDelphine CC Chiu {
3537bb4592aSDelphine CC Chiu bootSeq.front() |= BOOT_MODE_BOOT_FLAG;
3547bb4592aSDelphine CC Chiu }
3557bb4592aSDelphine CC Chiu
3567bb4592aSDelphine CC Chiu nlohmann::json bootModeJson = oemData[hostName][KEY_BOOT_MODE];
3577bb4592aSDelphine CC Chiu if (bootModeJson["CMOS_CLR"])
3587bb4592aSDelphine CC Chiu bootSeq.front() |= BOOT_MODE_CMOS_CLR;
3597bb4592aSDelphine CC Chiu
3607bb4592aSDelphine CC Chiu for (int i = 1; i < SIZE_BOOT_ORDER; i++)
3617bb4592aSDelphine CC Chiu {
3627bb4592aSDelphine CC Chiu std::string seqStr = oemData[hostName][KEY_BOOT_SEQ][i - 1];
3637bb4592aSDelphine CC Chiu if (bootMap.find(seqStr) != bootMap.end())
3647bb4592aSDelphine CC Chiu bootSeq.push_back(bootMap[seqStr]);
3657bb4592aSDelphine CC Chiu else
3667bb4592aSDelphine CC Chiu bootSeq.push_back(0xff);
3677bb4592aSDelphine CC Chiu }
3687bb4592aSDelphine CC Chiu }
3697bb4592aSDelphine CC Chiu
370f0cf6658SJayashree-D } // namespace boot
371f0cf6658SJayashree-D
3721d4a0697SVijay Khemka //----------------------------------------------------------------------
3731d4a0697SVijay Khemka // Helper functions for storing oem data
3741d4a0697SVijay Khemka //----------------------------------------------------------------------
3751d4a0697SVijay Khemka
flushOemData()3761d4a0697SVijay Khemka void flushOemData()
3771d4a0697SVijay Khemka {
3781d4a0697SVijay Khemka std::ofstream file(JSON_OEM_DATA_FILE);
3791d4a0697SVijay Khemka file << oemData;
380feaa9811SVijay Khemka file.close();
3811d4a0697SVijay Khemka return;
3821d4a0697SVijay Khemka }
3831d4a0697SVijay Khemka
bytesToStr(uint8_t * byte,int len)3841d4a0697SVijay Khemka std::string bytesToStr(uint8_t* byte, int len)
3851d4a0697SVijay Khemka {
3861d4a0697SVijay Khemka std::stringstream ss;
3871d4a0697SVijay Khemka int i;
3881d4a0697SVijay Khemka
3891d4a0697SVijay Khemka ss << std::hex;
3901d4a0697SVijay Khemka for (i = 0; i < len; i++)
3911d4a0697SVijay Khemka {
3921d4a0697SVijay Khemka ss << std::setw(2) << std::setfill('0') << (int)byte[i];
3931d4a0697SVijay Khemka }
3941d4a0697SVijay Khemka
3951d4a0697SVijay Khemka return ss.str();
3961d4a0697SVijay Khemka }
3971d4a0697SVijay Khemka
strToBytes(std::string & str,uint8_t * data)3981d4a0697SVijay Khemka int strToBytes(std::string& str, uint8_t* data)
3991d4a0697SVijay Khemka {
4001d4a0697SVijay Khemka std::string sstr;
401e39f9393SWilly Tu size_t i;
4021d4a0697SVijay Khemka
4031d4a0697SVijay Khemka for (i = 0; i < (str.length()) / 2; i++)
4041d4a0697SVijay Khemka {
4051d4a0697SVijay Khemka sstr = str.substr(i * 2, 2);
4061d4a0697SVijay Khemka data[i] = (uint8_t)std::strtol(sstr.c_str(), NULL, 16);
4071d4a0697SVijay Khemka }
4081d4a0697SVijay Khemka return i;
4091d4a0697SVijay Khemka }
4101d4a0697SVijay Khemka
readDimmType(std::string & data,uint8_t param)41110ff3d86SKarthikeyan Pasupathi int readDimmType(std::string& data, uint8_t param)
41210ff3d86SKarthikeyan Pasupathi {
41310ff3d86SKarthikeyan Pasupathi nlohmann::json dimmObj;
41410ff3d86SKarthikeyan Pasupathi /* Get dimm type names stored in json file */
41510ff3d86SKarthikeyan Pasupathi std::ifstream file(JSON_DIMM_TYPE_FILE);
41610ff3d86SKarthikeyan Pasupathi if (file)
41710ff3d86SKarthikeyan Pasupathi {
41810ff3d86SKarthikeyan Pasupathi file >> dimmObj;
41910ff3d86SKarthikeyan Pasupathi file.close();
42010ff3d86SKarthikeyan Pasupathi }
42110ff3d86SKarthikeyan Pasupathi else
42210ff3d86SKarthikeyan Pasupathi {
42310ff3d86SKarthikeyan Pasupathi phosphor::logging::log<phosphor::logging::level::ERR>(
42410ff3d86SKarthikeyan Pasupathi "DIMM type names file not found",
42510ff3d86SKarthikeyan Pasupathi phosphor::logging::entry("DIMM_TYPE_FILE=%s", JSON_DIMM_TYPE_FILE));
42610ff3d86SKarthikeyan Pasupathi return -1;
42710ff3d86SKarthikeyan Pasupathi }
42810ff3d86SKarthikeyan Pasupathi
42910ff3d86SKarthikeyan Pasupathi std::string dimmKey = "dimm_type" + std::to_string(param);
43010ff3d86SKarthikeyan Pasupathi auto obj = dimmObj[dimmKey]["short_name"];
43110ff3d86SKarthikeyan Pasupathi data = obj;
43210ff3d86SKarthikeyan Pasupathi return 0;
43310ff3d86SKarthikeyan Pasupathi }
43410ff3d86SKarthikeyan Pasupathi
getNetworkData(uint8_t lan_param,char * data)4351b6fae3fSVijay Khemka ipmi_ret_t getNetworkData(uint8_t lan_param, char* data)
4361b6fae3fSVijay Khemka {
4371b6fae3fSVijay Khemka ipmi_ret_t rc = IPMI_CC_OK;
438cd315e07SPatrick Williams sdbusplus::bus_t bus(ipmid_get_sd_bus_connection());
4391b6fae3fSVijay Khemka
4401b6fae3fSVijay Khemka const std::string ethdevice = "eth0";
4411b6fae3fSVijay Khemka
4421b6fae3fSVijay Khemka switch (static_cast<LanParam>(lan_param))
4431b6fae3fSVijay Khemka {
444d1194024SVijay Khemka case LanParam::IP:
445d1194024SVijay Khemka {
4461b6fae3fSVijay Khemka std::string ipaddress;
447a7231893SVijay Khemka auto ipObjectInfo = ipmi::network::getIPObject(
4488d1a81e8SPotin Lai bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT,
4498d1a81e8SPotin Lai ipmi::network::IPV4_PROTOCOL, ethdevice);
4501b6fae3fSVijay Khemka
4511b6fae3fSVijay Khemka auto properties = ipmi::getAllDbusProperties(
4521b6fae3fSVijay Khemka bus, ipObjectInfo.second, ipObjectInfo.first,
4531b6fae3fSVijay Khemka ipmi::network::IP_INTERFACE);
4541b6fae3fSVijay Khemka
455ef0efbc4SPatrick Williams ipaddress = std::get<std::string>(properties["Address"]);
4561b6fae3fSVijay Khemka
4571b6fae3fSVijay Khemka std::strcpy(data, ipaddress.c_str());
4581b6fae3fSVijay Khemka }
4591b6fae3fSVijay Khemka break;
4601b6fae3fSVijay Khemka
461d1194024SVijay Khemka case LanParam::IPV6:
462d1194024SVijay Khemka {
4631b6fae3fSVijay Khemka std::string ipaddress;
464a7231893SVijay Khemka auto ipObjectInfo = ipmi::network::getIPObject(
4658d1a81e8SPotin Lai bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT,
4668d1a81e8SPotin Lai ipmi::network::IPV6_PROTOCOL, ethdevice);
4671b6fae3fSVijay Khemka
4681b6fae3fSVijay Khemka auto properties = ipmi::getAllDbusProperties(
4691b6fae3fSVijay Khemka bus, ipObjectInfo.second, ipObjectInfo.first,
4701b6fae3fSVijay Khemka ipmi::network::IP_INTERFACE);
4711b6fae3fSVijay Khemka
472ef0efbc4SPatrick Williams ipaddress = std::get<std::string>(properties["Address"]);
4731b6fae3fSVijay Khemka
4741b6fae3fSVijay Khemka std::strcpy(data, ipaddress.c_str());
4751b6fae3fSVijay Khemka }
4761b6fae3fSVijay Khemka break;
4771b6fae3fSVijay Khemka
478d1194024SVijay Khemka case LanParam::MAC:
479d1194024SVijay Khemka {
4801b6fae3fSVijay Khemka std::string macAddress;
4811b6fae3fSVijay Khemka auto macObjectInfo =
4821b6fae3fSVijay Khemka ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
4831b6fae3fSVijay Khemka ipmi::network::ROOT, ethdevice);
4841b6fae3fSVijay Khemka
4851b6fae3fSVijay Khemka auto variant = ipmi::getDbusProperty(
4861b6fae3fSVijay Khemka bus, macObjectInfo.second, macObjectInfo.first,
4871b6fae3fSVijay Khemka ipmi::network::MAC_INTERFACE, "MACAddress");
4881b6fae3fSVijay Khemka
489ef0efbc4SPatrick Williams macAddress = std::get<std::string>(variant);
4901b6fae3fSVijay Khemka
4911b6fae3fSVijay Khemka sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
4921b6fae3fSVijay Khemka (data), (data + 1), (data + 2), (data + 3), (data + 4),
4931b6fae3fSVijay Khemka (data + 5));
4941b6fae3fSVijay Khemka std::strcpy(data, macAddress.c_str());
4951b6fae3fSVijay Khemka }
4961b6fae3fSVijay Khemka break;
4971b6fae3fSVijay Khemka
4981b6fae3fSVijay Khemka default:
4991b6fae3fSVijay Khemka rc = IPMI_CC_PARM_OUT_OF_RANGE;
5001b6fae3fSVijay Khemka }
5011b6fae3fSVijay Khemka return rc;
5021b6fae3fSVijay Khemka }
503e7d23d0eSVijay Khemka
isMultiHostPlatform()50439836ffaSKarthikeyan Pasupathi bool isMultiHostPlatform()
50539836ffaSKarthikeyan Pasupathi {
50639836ffaSKarthikeyan Pasupathi bool platform;
5074ec80567SJayashree Dhanapal if (hostInstances == "0")
50839836ffaSKarthikeyan Pasupathi {
50939836ffaSKarthikeyan Pasupathi platform = false;
51039836ffaSKarthikeyan Pasupathi }
51139836ffaSKarthikeyan Pasupathi else
51239836ffaSKarthikeyan Pasupathi {
51339836ffaSKarthikeyan Pasupathi platform = true;
51439836ffaSKarthikeyan Pasupathi }
51539836ffaSKarthikeyan Pasupathi return platform;
51639836ffaSKarthikeyan Pasupathi }
51739836ffaSKarthikeyan Pasupathi
518d8d95a3dSDaniel Hsu // return "" equals failed
getMotherBoardFruPath()519d8d95a3dSDaniel Hsu std::string getMotherBoardFruPath()
520d8d95a3dSDaniel Hsu {
521d8d95a3dSDaniel Hsu std::vector<std::string> paths;
522d8d95a3dSDaniel Hsu static constexpr const auto depth = 0;
523d8d95a3dSDaniel Hsu sdbusplus::bus_t dbus(ipmid_get_sd_bus_connection());
524d8d95a3dSDaniel Hsu
525d8d95a3dSDaniel Hsu auto mapperCall = dbus.new_method_call(
526d8d95a3dSDaniel Hsu "xyz.openbmc_project.ObjectMapper",
527d8d95a3dSDaniel Hsu "/xyz/openbmc_project/object_mapper",
528d8d95a3dSDaniel Hsu "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths");
529d8d95a3dSDaniel Hsu static constexpr auto interface = {
530d8d95a3dSDaniel Hsu "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
531d8d95a3dSDaniel Hsu
532d8d95a3dSDaniel Hsu mapperCall.append("/xyz/openbmc_project/inventory/", depth, interface);
533d8d95a3dSDaniel Hsu try
534d8d95a3dSDaniel Hsu {
535d8d95a3dSDaniel Hsu auto reply = dbus.call(mapperCall);
536d8d95a3dSDaniel Hsu reply.read(paths);
537d8d95a3dSDaniel Hsu }
538d8d95a3dSDaniel Hsu catch (sdbusplus::exception_t& e)
539d8d95a3dSDaniel Hsu {
540d8d95a3dSDaniel Hsu phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
541d8d95a3dSDaniel Hsu return "";
542d8d95a3dSDaniel Hsu }
543d8d95a3dSDaniel Hsu
544d8d95a3dSDaniel Hsu for (const auto& path : paths)
545d8d95a3dSDaniel Hsu {
546d8d95a3dSDaniel Hsu return path;
547d8d95a3dSDaniel Hsu }
548d8d95a3dSDaniel Hsu
549d8d95a3dSDaniel Hsu return "";
550d8d95a3dSDaniel Hsu }
551d8d95a3dSDaniel Hsu
552d8d95a3dSDaniel Hsu // return "" equals failed
getMotherBoardFruName()553d8d95a3dSDaniel Hsu std::string getMotherBoardFruName()
554d8d95a3dSDaniel Hsu {
555d8d95a3dSDaniel Hsu std::string path = getMotherBoardFruPath();
556d8d95a3dSDaniel Hsu std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
557d8d95a3dSDaniel Hsu std::string service = "xyz.openbmc_project.EntityManager";
558d8d95a3dSDaniel Hsu
559d8d95a3dSDaniel Hsu try
560d8d95a3dSDaniel Hsu {
561d8d95a3dSDaniel Hsu auto value = ipmi::getDbusProperty(
562d8d95a3dSDaniel Hsu *dbus, service, path, "xyz.openbmc_project.Inventory.Item.Board",
563d8d95a3dSDaniel Hsu "Name");
564d8d95a3dSDaniel Hsu return std::get<std::string>(value);
565d8d95a3dSDaniel Hsu }
566d8d95a3dSDaniel Hsu catch (sdbusplus::exception_t& e)
567d8d95a3dSDaniel Hsu {
568d8d95a3dSDaniel Hsu phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
569d8d95a3dSDaniel Hsu return "";
570d8d95a3dSDaniel Hsu }
571d8d95a3dSDaniel Hsu }
572d8d95a3dSDaniel Hsu
573e7d23d0eSVijay Khemka // return code: 0 successful
getFruData(std::string & data,std::string & name)574e7d23d0eSVijay Khemka int8_t getFruData(std::string& data, std::string& name)
575e7d23d0eSVijay Khemka {
57698aabdb1SKarthikeyan Pasupathi size_t pos;
57798aabdb1SKarthikeyan Pasupathi static constexpr const auto depth = 0;
57898aabdb1SKarthikeyan Pasupathi std::vector<std::string> paths;
57998aabdb1SKarthikeyan Pasupathi std::string machinePath;
580d8d95a3dSDaniel Hsu std::string baseBoard = getMotherBoardFruPath();
581d8d95a3dSDaniel Hsu baseBoard = baseBoard.empty() ? "Baseboard" : baseBoard;
58298aabdb1SKarthikeyan Pasupathi
58398aabdb1SKarthikeyan Pasupathi bool platform = isMultiHostPlatform();
58498aabdb1SKarthikeyan Pasupathi if (platform == true)
58598aabdb1SKarthikeyan Pasupathi {
586e1ff81faSKarthikeyan Pasupathi getSelectorPosition(pos);
58798aabdb1SKarthikeyan Pasupathi }
58898aabdb1SKarthikeyan Pasupathi
58998aabdb1SKarthikeyan Pasupathi sd_bus* bus = NULL;
59098aabdb1SKarthikeyan Pasupathi int ret = sd_bus_default_system(&bus);
59198aabdb1SKarthikeyan Pasupathi if (ret < 0)
592e7d23d0eSVijay Khemka {
593e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
59498aabdb1SKarthikeyan Pasupathi "Failed to connect to system bus",
59598aabdb1SKarthikeyan Pasupathi phosphor::logging::entry("ERRNO=0x%X", -ret));
59698aabdb1SKarthikeyan Pasupathi sd_bus_unref(bus);
597e7d23d0eSVijay Khemka return -1;
598e7d23d0eSVijay Khemka }
599cd315e07SPatrick Williams sdbusplus::bus_t dbus(bus);
600010dee04SPatrick Williams auto mapperCall = dbus.new_method_call(
60198aabdb1SKarthikeyan Pasupathi "xyz.openbmc_project.ObjectMapper",
602010dee04SPatrick Williams "/xyz/openbmc_project/object_mapper",
603010dee04SPatrick Williams "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths");
60498aabdb1SKarthikeyan Pasupathi static constexpr std::array<const char*, 1> interface = {
60598aabdb1SKarthikeyan Pasupathi "xyz.openbmc_project.Inventory.Decorator.Asset"};
60698aabdb1SKarthikeyan Pasupathi mapperCall.append("/xyz/openbmc_project/inventory/", depth, interface);
607e7d23d0eSVijay Khemka
608e7d23d0eSVijay Khemka try
609e7d23d0eSVijay Khemka {
61098aabdb1SKarthikeyan Pasupathi auto reply = dbus.call(mapperCall);
61198aabdb1SKarthikeyan Pasupathi reply.read(paths);
612e7d23d0eSVijay Khemka }
61398aabdb1SKarthikeyan Pasupathi catch (sdbusplus::exception_t& e)
614e7d23d0eSVijay Khemka {
615e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
616e7d23d0eSVijay Khemka return -1;
617e7d23d0eSVijay Khemka }
61898aabdb1SKarthikeyan Pasupathi
61998aabdb1SKarthikeyan Pasupathi for (const auto& path : paths)
62098aabdb1SKarthikeyan Pasupathi {
62198aabdb1SKarthikeyan Pasupathi if (platform == true)
62298aabdb1SKarthikeyan Pasupathi {
62398aabdb1SKarthikeyan Pasupathi if (pos == BMC_POS)
62498aabdb1SKarthikeyan Pasupathi {
62598aabdb1SKarthikeyan Pasupathi machinePath = baseBoard;
62698aabdb1SKarthikeyan Pasupathi }
62798aabdb1SKarthikeyan Pasupathi else
62898aabdb1SKarthikeyan Pasupathi {
62998aabdb1SKarthikeyan Pasupathi machinePath = "_" + std::to_string(pos);
63098aabdb1SKarthikeyan Pasupathi }
63198aabdb1SKarthikeyan Pasupathi }
63298aabdb1SKarthikeyan Pasupathi else
63398aabdb1SKarthikeyan Pasupathi {
63498aabdb1SKarthikeyan Pasupathi machinePath = baseBoard;
63598aabdb1SKarthikeyan Pasupathi }
63698aabdb1SKarthikeyan Pasupathi
63798aabdb1SKarthikeyan Pasupathi auto found = path.find(machinePath);
638123cbcc4SPatrick Williams if (found == std::string::npos)
63998aabdb1SKarthikeyan Pasupathi {
64098aabdb1SKarthikeyan Pasupathi continue;
64198aabdb1SKarthikeyan Pasupathi }
64298aabdb1SKarthikeyan Pasupathi
64398aabdb1SKarthikeyan Pasupathi std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
64498aabdb1SKarthikeyan Pasupathi std::string service = getService(
64598aabdb1SKarthikeyan Pasupathi *dbus, "xyz.openbmc_project.Inventory.Decorator.Asset", path);
64698aabdb1SKarthikeyan Pasupathi
64798aabdb1SKarthikeyan Pasupathi auto Value = ipmi::getDbusProperty(
64898aabdb1SKarthikeyan Pasupathi *dbus, service, path,
64998aabdb1SKarthikeyan Pasupathi "xyz.openbmc_project.Inventory.Decorator.Asset", name);
65098aabdb1SKarthikeyan Pasupathi
65198aabdb1SKarthikeyan Pasupathi data = std::get<std::string>(Value);
65298aabdb1SKarthikeyan Pasupathi return 0;
653e7d23d0eSVijay Khemka }
654e7d23d0eSVijay Khemka return -1;
655e7d23d0eSVijay Khemka }
656e7d23d0eSVijay Khemka
sysConfig(std::vector<std::string> & data,size_t pos)65710ff3d86SKarthikeyan Pasupathi int8_t sysConfig(std::vector<std::string>& data, size_t pos)
65810ff3d86SKarthikeyan Pasupathi {
65910ff3d86SKarthikeyan Pasupathi nlohmann::json sysObj;
66010ff3d86SKarthikeyan Pasupathi std::string dimmInfo = KEY_Q_DIMM_INFO + std::to_string(pos);
66110ff3d86SKarthikeyan Pasupathi std::string result, typeName;
66210ff3d86SKarthikeyan Pasupathi uint8_t res[MAX_BUF];
66310ff3d86SKarthikeyan Pasupathi
66410ff3d86SKarthikeyan Pasupathi /* Get sysConfig data stored in json file */
66510ff3d86SKarthikeyan Pasupathi std::ifstream file(JSON_OEM_DATA_FILE);
66610ff3d86SKarthikeyan Pasupathi if (file)
66710ff3d86SKarthikeyan Pasupathi {
66810ff3d86SKarthikeyan Pasupathi file >> sysObj;
66910ff3d86SKarthikeyan Pasupathi file.close();
67010ff3d86SKarthikeyan Pasupathi }
67110ff3d86SKarthikeyan Pasupathi else
67210ff3d86SKarthikeyan Pasupathi {
67310ff3d86SKarthikeyan Pasupathi phosphor::logging::log<phosphor::logging::level::ERR>(
67410ff3d86SKarthikeyan Pasupathi "oemData file not found",
67510ff3d86SKarthikeyan Pasupathi phosphor::logging::entry("OEM_DATA_FILE=%s", JSON_OEM_DATA_FILE));
67610ff3d86SKarthikeyan Pasupathi return -1;
67710ff3d86SKarthikeyan Pasupathi }
67810ff3d86SKarthikeyan Pasupathi
67910ff3d86SKarthikeyan Pasupathi if (sysObj.find(dimmInfo) == sysObj.end())
68010ff3d86SKarthikeyan Pasupathi {
68110ff3d86SKarthikeyan Pasupathi phosphor::logging::log<phosphor::logging::level::ERR>(
68210ff3d86SKarthikeyan Pasupathi "sysconfig key not available",
68310ff3d86SKarthikeyan Pasupathi phosphor::logging::entry("SYS_JSON_KEY=%s", dimmInfo.c_str()));
68410ff3d86SKarthikeyan Pasupathi return -1;
68510ff3d86SKarthikeyan Pasupathi }
68610ff3d86SKarthikeyan Pasupathi /* Get dimm type names stored in json file */
68710ff3d86SKarthikeyan Pasupathi nlohmann::json dimmObj;
68810ff3d86SKarthikeyan Pasupathi std::ifstream dimmFile(JSON_DIMM_TYPE_FILE);
68910ff3d86SKarthikeyan Pasupathi if (file)
69010ff3d86SKarthikeyan Pasupathi {
69110ff3d86SKarthikeyan Pasupathi dimmFile >> dimmObj;
69210ff3d86SKarthikeyan Pasupathi dimmFile.close();
69310ff3d86SKarthikeyan Pasupathi }
69410ff3d86SKarthikeyan Pasupathi else
69510ff3d86SKarthikeyan Pasupathi {
69610ff3d86SKarthikeyan Pasupathi phosphor::logging::log<phosphor::logging::level::ERR>(
69710ff3d86SKarthikeyan Pasupathi "DIMM type names file not found",
69810ff3d86SKarthikeyan Pasupathi phosphor::logging::entry("DIMM_TYPE_FILE=%s", JSON_DIMM_TYPE_FILE));
69910ff3d86SKarthikeyan Pasupathi return -1;
70010ff3d86SKarthikeyan Pasupathi }
70110ff3d86SKarthikeyan Pasupathi std::vector<std::string> a;
70210ff3d86SKarthikeyan Pasupathi for (auto& j : dimmObj.items())
70310ff3d86SKarthikeyan Pasupathi {
70410ff3d86SKarthikeyan Pasupathi std::string name = j.key();
70510ff3d86SKarthikeyan Pasupathi a.push_back(name);
70610ff3d86SKarthikeyan Pasupathi }
70710ff3d86SKarthikeyan Pasupathi
70810ff3d86SKarthikeyan Pasupathi uint8_t len = a.size();
70910ff3d86SKarthikeyan Pasupathi for (uint8_t ii = 0; ii < len; ii++)
71010ff3d86SKarthikeyan Pasupathi {
71110ff3d86SKarthikeyan Pasupathi std::string indKey = std::to_string(ii);
71210ff3d86SKarthikeyan Pasupathi std::string speedSize = sysObj[dimmInfo][indKey][DIMM_SPEED];
71310ff3d86SKarthikeyan Pasupathi strToBytes(speedSize, res);
71410ff3d86SKarthikeyan Pasupathi auto speed = (res[1] << 8 | res[0]);
71510ff3d86SKarthikeyan Pasupathi size_t dimmSize = ((res[3] << 8 | res[2]) / 1000);
71610ff3d86SKarthikeyan Pasupathi
71710ff3d86SKarthikeyan Pasupathi if (dimmSize == 0)
71810ff3d86SKarthikeyan Pasupathi {
71910ff3d86SKarthikeyan Pasupathi std::cerr << "Dimm information not available for slot_" +
72010ff3d86SKarthikeyan Pasupathi std::to_string(ii)
72110ff3d86SKarthikeyan Pasupathi << std::endl;
72210ff3d86SKarthikeyan Pasupathi continue;
72310ff3d86SKarthikeyan Pasupathi }
72410ff3d86SKarthikeyan Pasupathi std::string type = sysObj[dimmInfo][indKey][DIMM_TYPE];
72510ff3d86SKarthikeyan Pasupathi std::string dualInlineMem = sysObj[dimmInfo][indKey][KEY_DIMM_TYPE];
72610ff3d86SKarthikeyan Pasupathi strToBytes(type, res);
72710ff3d86SKarthikeyan Pasupathi size_t dimmType = res[0];
72810ff3d86SKarthikeyan Pasupathi if (dimmVenMap.find(dimmType) == dimmVenMap.end())
72910ff3d86SKarthikeyan Pasupathi {
73010ff3d86SKarthikeyan Pasupathi typeName = "unknown";
73110ff3d86SKarthikeyan Pasupathi }
73210ff3d86SKarthikeyan Pasupathi else
73310ff3d86SKarthikeyan Pasupathi {
73410ff3d86SKarthikeyan Pasupathi typeName = dimmVenMap[dimmType];
73510ff3d86SKarthikeyan Pasupathi }
73610ff3d86SKarthikeyan Pasupathi result = dualInlineMem + "/" + typeName + "/" + std::to_string(speed) +
73710ff3d86SKarthikeyan Pasupathi "MHz" + "/" + std::to_string(dimmSize) + "GB";
73810ff3d86SKarthikeyan Pasupathi data.push_back(result);
73910ff3d86SKarthikeyan Pasupathi }
74010ff3d86SKarthikeyan Pasupathi return 0;
74110ff3d86SKarthikeyan Pasupathi }
74210ff3d86SKarthikeyan Pasupathi
procInfo(std::string & result,size_t pos)743d532fecaSKarthikeyan Pasupathi int8_t procInfo(std::string& result, size_t pos)
744d532fecaSKarthikeyan Pasupathi {
745d532fecaSKarthikeyan Pasupathi std::vector<char> data;
746d532fecaSKarthikeyan Pasupathi uint8_t res[MAX_BUF];
747d532fecaSKarthikeyan Pasupathi std::string procIndex = "00";
748d532fecaSKarthikeyan Pasupathi nlohmann::json proObj;
749d532fecaSKarthikeyan Pasupathi std::string procInfo = KEY_Q_PROC_INFO + std::to_string(pos);
750d532fecaSKarthikeyan Pasupathi /* Get processor data stored in json file */
751d532fecaSKarthikeyan Pasupathi std::ifstream file(JSON_OEM_DATA_FILE);
752d532fecaSKarthikeyan Pasupathi if (file)
753d532fecaSKarthikeyan Pasupathi {
754d532fecaSKarthikeyan Pasupathi file >> proObj;
755d532fecaSKarthikeyan Pasupathi file.close();
756d532fecaSKarthikeyan Pasupathi }
757d532fecaSKarthikeyan Pasupathi else
758d532fecaSKarthikeyan Pasupathi {
759d532fecaSKarthikeyan Pasupathi phosphor::logging::log<phosphor::logging::level::ERR>(
760d532fecaSKarthikeyan Pasupathi "oemData file not found",
761d532fecaSKarthikeyan Pasupathi phosphor::logging::entry("OEM_DATA_FILE=%s", JSON_OEM_DATA_FILE));
762d532fecaSKarthikeyan Pasupathi return -1;
763d532fecaSKarthikeyan Pasupathi }
764d532fecaSKarthikeyan Pasupathi if (proObj.find(procInfo) == proObj.end())
765d532fecaSKarthikeyan Pasupathi {
766d532fecaSKarthikeyan Pasupathi phosphor::logging::log<phosphor::logging::level::ERR>(
767d532fecaSKarthikeyan Pasupathi "processor info key not available",
768d532fecaSKarthikeyan Pasupathi phosphor::logging::entry("PROC_JSON_KEY=%s", procInfo.c_str()));
769d532fecaSKarthikeyan Pasupathi return -1;
770d532fecaSKarthikeyan Pasupathi }
771d532fecaSKarthikeyan Pasupathi std::string procName = proObj[procInfo][procIndex][KEY_PROC_NAME];
772d532fecaSKarthikeyan Pasupathi std::string basicInfo = proObj[procInfo][procIndex][KEY_BASIC_INFO];
773d532fecaSKarthikeyan Pasupathi // Processor Product Name
774d532fecaSKarthikeyan Pasupathi strToBytes(procName, res);
775d532fecaSKarthikeyan Pasupathi data.assign(reinterpret_cast<char*>(&res),
776d532fecaSKarthikeyan Pasupathi reinterpret_cast<char*>(&res) + sizeof(res));
777d532fecaSKarthikeyan Pasupathi
778d532fecaSKarthikeyan Pasupathi std::string s(data.begin(), data.end());
779d532fecaSKarthikeyan Pasupathi std::regex regex(" ");
780d532fecaSKarthikeyan Pasupathi std::vector<std::string> productName(
781d532fecaSKarthikeyan Pasupathi std::sregex_token_iterator(s.begin(), s.end(), regex, -1),
782d532fecaSKarthikeyan Pasupathi std::sregex_token_iterator());
783d532fecaSKarthikeyan Pasupathi
784d532fecaSKarthikeyan Pasupathi // Processor core and frequency
785d532fecaSKarthikeyan Pasupathi strToBytes(basicInfo, res);
786d532fecaSKarthikeyan Pasupathi uint16_t coreNum = res[0];
787d532fecaSKarthikeyan Pasupathi double procFrequency = (float)(res[4] << 8 | res[3]) / 1000;
788d532fecaSKarthikeyan Pasupathi result = "CPU:" + productName[2] + "/" + std::to_string(procFrequency) +
789d532fecaSKarthikeyan Pasupathi "GHz" + "/" + std::to_string(coreNum) + "c";
790d532fecaSKarthikeyan Pasupathi return 0;
791d532fecaSKarthikeyan Pasupathi }
792d532fecaSKarthikeyan Pasupathi
793e7d23d0eSVijay Khemka typedef struct
794e7d23d0eSVijay Khemka {
795e7d23d0eSVijay Khemka uint8_t cur_power_state;
796e7d23d0eSVijay Khemka uint8_t last_power_event;
797e7d23d0eSVijay Khemka uint8_t misc_power_state;
798e7d23d0eSVijay Khemka uint8_t front_panel_button_cap_status;
799e7d23d0eSVijay Khemka } ipmi_get_chassis_status_t;
800e7d23d0eSVijay Khemka
801e7d23d0eSVijay Khemka //----------------------------------------------------------------------
802e7d23d0eSVijay Khemka // Get Debug Frame Info
803e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemDbgGetFrameInfo(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t response,ipmi_data_len_t data_len,ipmi_context_t)804010dee04SPatrick Williams ipmi_ret_t ipmiOemDbgGetFrameInfo(
805010dee04SPatrick Williams ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request, ipmi_response_t response,
806e39f9393SWilly Tu ipmi_data_len_t data_len, ipmi_context_t)
807e7d23d0eSVijay Khemka {
808e7d23d0eSVijay Khemka uint8_t* req = reinterpret_cast<uint8_t*>(request);
809e7d23d0eSVijay Khemka uint8_t* res = reinterpret_cast<uint8_t*>(response);
810b340aa28SPeter Yin uint8_t num_frames = debugCardFrameSize;
811e7d23d0eSVijay Khemka
812e7d23d0eSVijay Khemka std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
813e7d23d0eSVijay Khemka res[SIZE_IANA_ID] = num_frames;
814e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID + 1;
815e7d23d0eSVijay Khemka
816e7d23d0eSVijay Khemka return IPMI_CC_OK;
817e7d23d0eSVijay Khemka }
818e7d23d0eSVijay Khemka
819e7d23d0eSVijay Khemka //----------------------------------------------------------------------
820e7d23d0eSVijay Khemka // Get Debug Updated Frames
821e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemDbgGetUpdFrames(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t response,ipmi_data_len_t data_len,ipmi_context_t)822010dee04SPatrick Williams ipmi_ret_t ipmiOemDbgGetUpdFrames(
823010dee04SPatrick Williams ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request, ipmi_response_t response,
824e39f9393SWilly Tu ipmi_data_len_t data_len, ipmi_context_t)
825e7d23d0eSVijay Khemka {
826e7d23d0eSVijay Khemka uint8_t* req = reinterpret_cast<uint8_t*>(request);
827e7d23d0eSVijay Khemka uint8_t* res = reinterpret_cast<uint8_t*>(response);
828e7d23d0eSVijay Khemka uint8_t num_updates = 3;
829e7d23d0eSVijay Khemka *data_len = 4;
830e7d23d0eSVijay Khemka
831e7d23d0eSVijay Khemka std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
832e7d23d0eSVijay Khemka res[SIZE_IANA_ID] = num_updates;
833e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID + num_updates + 1;
834e7d23d0eSVijay Khemka res[SIZE_IANA_ID + 1] = 1; // info page update
835e7d23d0eSVijay Khemka res[SIZE_IANA_ID + 2] = 2; // cri sel update
836e7d23d0eSVijay Khemka res[SIZE_IANA_ID + 3] = 3; // cri sensor update
837e7d23d0eSVijay Khemka
838e7d23d0eSVijay Khemka return IPMI_CC_OK;
839e7d23d0eSVijay Khemka }
840e7d23d0eSVijay Khemka
841e7d23d0eSVijay Khemka //----------------------------------------------------------------------
842e7d23d0eSVijay Khemka // Get Debug POST Description
843e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemDbgGetPostDesc(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t response,ipmi_data_len_t data_len,ipmi_context_t)844010dee04SPatrick Williams ipmi_ret_t ipmiOemDbgGetPostDesc(
845010dee04SPatrick Williams ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request, ipmi_response_t response,
846e39f9393SWilly Tu ipmi_data_len_t data_len, ipmi_context_t)
847e7d23d0eSVijay Khemka {
848e7d23d0eSVijay Khemka uint8_t* req = reinterpret_cast<uint8_t*>(request);
849e7d23d0eSVijay Khemka uint8_t* res = reinterpret_cast<uint8_t*>(response);
850e7d23d0eSVijay Khemka uint8_t index = 0;
851e7d23d0eSVijay Khemka uint8_t next = 0;
852e7d23d0eSVijay Khemka uint8_t end = 0;
853e7d23d0eSVijay Khemka uint8_t phase = 0;
854cc0d6d92SVijay Khemka uint8_t descLen = 0;
855e7d23d0eSVijay Khemka int ret;
856e7d23d0eSVijay Khemka
857e7d23d0eSVijay Khemka index = req[3];
858e7d23d0eSVijay Khemka phase = req[4];
859e7d23d0eSVijay Khemka
860cc0d6d92SVijay Khemka ret = plat_udbg_get_post_desc(index, &next, phase, &end, &descLen, &res[8]);
861e7d23d0eSVijay Khemka if (ret)
862e7d23d0eSVijay Khemka {
863e7d23d0eSVijay Khemka memcpy(res, req, SIZE_IANA_ID); // IANA ID
864e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID;
865e7d23d0eSVijay Khemka return IPMI_CC_UNSPECIFIED_ERROR;
866e7d23d0eSVijay Khemka }
867e7d23d0eSVijay Khemka
868e7d23d0eSVijay Khemka memcpy(res, req, SIZE_IANA_ID); // IANA ID
869e7d23d0eSVijay Khemka res[3] = index;
870e7d23d0eSVijay Khemka res[4] = next;
871e7d23d0eSVijay Khemka res[5] = phase;
872e7d23d0eSVijay Khemka res[6] = end;
873cc0d6d92SVijay Khemka res[7] = descLen;
874cc0d6d92SVijay Khemka *data_len = SIZE_IANA_ID + 5 + descLen;
875e7d23d0eSVijay Khemka
876e7d23d0eSVijay Khemka return IPMI_CC_OK;
877e7d23d0eSVijay Khemka }
878e7d23d0eSVijay Khemka
879e7d23d0eSVijay Khemka //----------------------------------------------------------------------
880e7d23d0eSVijay Khemka // Get Debug GPIO Description
881e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemDbgGetGpioDesc(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t response,ipmi_data_len_t data_len,ipmi_context_t)882010dee04SPatrick Williams ipmi_ret_t ipmiOemDbgGetGpioDesc(
883010dee04SPatrick Williams ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request, ipmi_response_t response,
884e39f9393SWilly Tu ipmi_data_len_t data_len, ipmi_context_t)
885e7d23d0eSVijay Khemka {
886e7d23d0eSVijay Khemka uint8_t* req = reinterpret_cast<uint8_t*>(request);
887e7d23d0eSVijay Khemka uint8_t* res = reinterpret_cast<uint8_t*>(response);
888e7d23d0eSVijay Khemka
88938183d66SVijay Khemka uint8_t index = 0;
89038183d66SVijay Khemka uint8_t next = 0;
89138183d66SVijay Khemka uint8_t level = 0;
89238183d66SVijay Khemka uint8_t pinDef = 0;
89338183d66SVijay Khemka uint8_t descLen = 0;
89438183d66SVijay Khemka int ret;
895e7d23d0eSVijay Khemka
89638183d66SVijay Khemka index = req[3];
89738183d66SVijay Khemka
89838183d66SVijay Khemka ret = plat_udbg_get_gpio_desc(index, &next, &level, &pinDef, &descLen,
89938183d66SVijay Khemka &res[8]);
90038183d66SVijay Khemka if (ret)
90138183d66SVijay Khemka {
90238183d66SVijay Khemka memcpy(res, req, SIZE_IANA_ID); // IANA ID
90338183d66SVijay Khemka *data_len = SIZE_IANA_ID;
90438183d66SVijay Khemka return IPMI_CC_UNSPECIFIED_ERROR;
90538183d66SVijay Khemka }
90638183d66SVijay Khemka
90738183d66SVijay Khemka memcpy(res, req, SIZE_IANA_ID); // IANA ID
90838183d66SVijay Khemka res[3] = index;
90938183d66SVijay Khemka res[4] = next;
91038183d66SVijay Khemka res[5] = level;
91138183d66SVijay Khemka res[6] = pinDef;
91238183d66SVijay Khemka res[7] = descLen;
91338183d66SVijay Khemka *data_len = SIZE_IANA_ID + 5 + descLen;
914e7d23d0eSVijay Khemka
915e7d23d0eSVijay Khemka return IPMI_CC_OK;
916e7d23d0eSVijay Khemka }
917e7d23d0eSVijay Khemka
918e7d23d0eSVijay Khemka //----------------------------------------------------------------------
919e7d23d0eSVijay Khemka // Get Debug Frame Data
920e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemDbgGetFrameData(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t response,ipmi_data_len_t data_len,ipmi_context_t)921010dee04SPatrick Williams ipmi_ret_t ipmiOemDbgGetFrameData(
922010dee04SPatrick Williams ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request, ipmi_response_t response,
923e39f9393SWilly Tu ipmi_data_len_t data_len, ipmi_context_t)
924e7d23d0eSVijay Khemka {
925e7d23d0eSVijay Khemka uint8_t* req = reinterpret_cast<uint8_t*>(request);
926e7d23d0eSVijay Khemka uint8_t* res = reinterpret_cast<uint8_t*>(response);
927e7d23d0eSVijay Khemka uint8_t frame;
928e7d23d0eSVijay Khemka uint8_t page;
929e7d23d0eSVijay Khemka uint8_t next;
930e7d23d0eSVijay Khemka uint8_t count;
931e7d23d0eSVijay Khemka int ret;
932e7d23d0eSVijay Khemka
933e7d23d0eSVijay Khemka frame = req[3];
934e7d23d0eSVijay Khemka page = req[4];
935e7d23d0eSVijay Khemka
936e7d23d0eSVijay Khemka ret = plat_udbg_get_frame_data(frame, page, &next, &count, &res[7]);
937e7d23d0eSVijay Khemka if (ret)
938e7d23d0eSVijay Khemka {
939e7d23d0eSVijay Khemka memcpy(res, req, SIZE_IANA_ID); // IANA ID
940e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID;
941e7d23d0eSVijay Khemka return IPMI_CC_UNSPECIFIED_ERROR;
942e7d23d0eSVijay Khemka }
943e7d23d0eSVijay Khemka
944e7d23d0eSVijay Khemka memcpy(res, req, SIZE_IANA_ID); // IANA ID
945e7d23d0eSVijay Khemka res[3] = frame;
946e7d23d0eSVijay Khemka res[4] = page;
947e7d23d0eSVijay Khemka res[5] = next;
948e7d23d0eSVijay Khemka res[6] = count;
949e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID + 4 + count;
950e7d23d0eSVijay Khemka
951e7d23d0eSVijay Khemka return IPMI_CC_OK;
952e7d23d0eSVijay Khemka }
953e7d23d0eSVijay Khemka
954e7d23d0eSVijay Khemka //----------------------------------------------------------------------
955e7d23d0eSVijay Khemka // Get Debug Control Panel
956e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemDbgGetCtrlPanel(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t response,ipmi_data_len_t data_len,ipmi_context_t)957010dee04SPatrick Williams ipmi_ret_t ipmiOemDbgGetCtrlPanel(
958010dee04SPatrick Williams ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request, ipmi_response_t response,
959e39f9393SWilly Tu ipmi_data_len_t data_len, ipmi_context_t)
960e7d23d0eSVijay Khemka {
961e7d23d0eSVijay Khemka uint8_t* req = reinterpret_cast<uint8_t*>(request);
962e7d23d0eSVijay Khemka uint8_t* res = reinterpret_cast<uint8_t*>(response);
963e7d23d0eSVijay Khemka
964e7d23d0eSVijay Khemka uint8_t panel;
965e7d23d0eSVijay Khemka uint8_t operation;
966e7d23d0eSVijay Khemka uint8_t item;
967e7d23d0eSVijay Khemka uint8_t count;
968e7d23d0eSVijay Khemka ipmi_ret_t ret;
969e7d23d0eSVijay Khemka
970e7d23d0eSVijay Khemka panel = req[3];
971e7d23d0eSVijay Khemka operation = req[4];
972e7d23d0eSVijay Khemka item = req[5];
973e7d23d0eSVijay Khemka
974e7d23d0eSVijay Khemka ret = plat_udbg_control_panel(panel, operation, item, &count, &res[3]);
975e7d23d0eSVijay Khemka
976e7d23d0eSVijay Khemka std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
977e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID + count;
978e7d23d0eSVijay Khemka
979e7d23d0eSVijay Khemka return ret;
980e7d23d0eSVijay Khemka }
981e7d23d0eSVijay Khemka
982e7d23d0eSVijay Khemka //----------------------------------------------------------------------
983e7d23d0eSVijay Khemka // Set Dimm Info (CMD_OEM_SET_DIMM_INFO)
984e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemSetDimmInfo(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t,ipmi_data_len_t data_len,ipmi_context_t)985e39f9393SWilly Tu ipmi_ret_t ipmiOemSetDimmInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
986e39f9393SWilly Tu ipmi_response_t, ipmi_data_len_t data_len,
987e39f9393SWilly Tu ipmi_context_t)
988e7d23d0eSVijay Khemka {
989e7d23d0eSVijay Khemka uint8_t* req = reinterpret_cast<uint8_t*>(request);
9901d4a0697SVijay Khemka
9911d4a0697SVijay Khemka uint8_t index = req[0];
9921d4a0697SVijay Khemka uint8_t type = req[1];
9931d4a0697SVijay Khemka uint16_t speed;
9941d4a0697SVijay Khemka uint32_t size;
9951d4a0697SVijay Khemka
9961d4a0697SVijay Khemka memcpy(&speed, &req[2], 2);
9971d4a0697SVijay Khemka memcpy(&size, &req[4], 4);
9981d4a0697SVijay Khemka
9991d4a0697SVijay Khemka std::stringstream ss;
10001d4a0697SVijay Khemka ss << std::hex;
10011d4a0697SVijay Khemka ss << std::setw(2) << std::setfill('0') << (int)index;
10021d4a0697SVijay Khemka
10031d4a0697SVijay Khemka oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_INDEX] = index;
10041d4a0697SVijay Khemka oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_TYPE] = type;
10051d4a0697SVijay Khemka oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_SPEED] = speed;
10061d4a0697SVijay Khemka oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_SIZE] = size;
10071d4a0697SVijay Khemka
10081d4a0697SVijay Khemka flushOemData();
10091d4a0697SVijay Khemka
10101d4a0697SVijay Khemka *data_len = 0;
10111d4a0697SVijay Khemka
10121d4a0697SVijay Khemka return IPMI_CC_OK;
10131d4a0697SVijay Khemka }
10141d4a0697SVijay Khemka
10151d4a0697SVijay Khemka //----------------------------------------------------------------------
10161d4a0697SVijay Khemka // Get Board ID (CMD_OEM_GET_BOARD_ID)
10171d4a0697SVijay Khemka //----------------------------------------------------------------------
ipmiOemGetBoardID(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t,ipmi_response_t,ipmi_data_len_t data_len,ipmi_context_t)1018e39f9393SWilly Tu ipmi_ret_t ipmiOemGetBoardID(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
1019e39f9393SWilly Tu ipmi_response_t, ipmi_data_len_t data_len,
1020e39f9393SWilly Tu ipmi_context_t)
10211d4a0697SVijay Khemka {
10221d4a0697SVijay Khemka /* TODO: Needs to implement this after GPIO implementation */
1023e7d23d0eSVijay Khemka *data_len = 0;
1024e7d23d0eSVijay Khemka
1025e7d23d0eSVijay Khemka return IPMI_CC_OK;
1026e7d23d0eSVijay Khemka }
1027e7d23d0eSVijay Khemka
10284ae63e71SBonnie Lo //----------------------------------------------------------------------
10294ae63e71SBonnie Lo // Get port 80 record (CMD_OEM_GET_80PORT_RECORD)
10304ae63e71SBonnie Lo //----------------------------------------------------------------------
10314ae63e71SBonnie Lo ipmi::RspType<std::vector<uint8_t>>
ipmiOemGet80PortRecord(ipmi::Context::ptr ctx)10324ae63e71SBonnie Lo ipmiOemGet80PortRecord(ipmi::Context::ptr ctx)
10334ae63e71SBonnie Lo {
10344ae63e71SBonnie Lo auto postCodeService = "xyz.openbmc_project.State.Boot.PostCode" +
10354ae63e71SBonnie Lo std::to_string(ctx->hostIdx + 1);
10364ae63e71SBonnie Lo auto postCodeObjPath = "/xyz/openbmc_project/State/Boot/PostCode" +
10374ae63e71SBonnie Lo std::to_string(ctx->hostIdx + 1);
10384ae63e71SBonnie Lo constexpr auto postCodeInterface =
10394ae63e71SBonnie Lo "xyz.openbmc_project.State.Boot.PostCode";
10404ae63e71SBonnie Lo const static uint16_t lastestPostCodeIndex = 1;
10414ae63e71SBonnie Lo constexpr const auto maxPostCodeLen =
10424ae63e71SBonnie Lo 224; // The length must be lower than IPMB limitation
10434ae63e71SBonnie Lo size_t startIndex = 0;
10444ae63e71SBonnie Lo
10454ae63e71SBonnie Lo std::vector<std::tuple<uint64_t, std::vector<uint8_t>>> postCodes;
10464ae63e71SBonnie Lo std::vector<uint8_t> resData;
10474ae63e71SBonnie Lo
10484ae63e71SBonnie Lo auto conn = getSdBus();
10494ae63e71SBonnie Lo /* Get the post codes by calling GetPostCodes method */
1050010dee04SPatrick Williams auto msg =
1051010dee04SPatrick Williams conn->new_method_call(postCodeService.c_str(), postCodeObjPath.c_str(),
1052010dee04SPatrick Williams postCodeInterface, "GetPostCodes");
10534ae63e71SBonnie Lo msg.append(lastestPostCodeIndex);
10544ae63e71SBonnie Lo
10554ae63e71SBonnie Lo try
10564ae63e71SBonnie Lo {
10574ae63e71SBonnie Lo auto reply = conn->call(msg);
10584ae63e71SBonnie Lo reply.read(postCodes);
10594ae63e71SBonnie Lo }
10604ae63e71SBonnie Lo catch (const sdbusplus::exception::SdBusError& e)
10614ae63e71SBonnie Lo {
10624ae63e71SBonnie Lo phosphor::logging::log<phosphor::logging::level::ERR>(
10634ae63e71SBonnie Lo "IPMI Get80PortRecord Failed in call method",
10644ae63e71SBonnie Lo phosphor::logging::entry("ERROR=%s", e.what()));
10654ae63e71SBonnie Lo return ipmi::responseUnspecifiedError();
10664ae63e71SBonnie Lo }
10674ae63e71SBonnie Lo
10684ae63e71SBonnie Lo /* Get post code data */
10694ae63e71SBonnie Lo for (size_t i = 0; i < postCodes.size(); ++i)
10704ae63e71SBonnie Lo {
10714ae63e71SBonnie Lo uint64_t primaryPostCode = std::get<uint64_t>(postCodes[i]);
10724ae63e71SBonnie Lo for (int j = postCodeSize - 1; j >= 0; --j)
10734ae63e71SBonnie Lo {
10744ae63e71SBonnie Lo uint8_t postCode =
10754ae63e71SBonnie Lo ((primaryPostCode >> (sizeof(uint64_t) * j)) & 0xFF);
10764ae63e71SBonnie Lo resData.emplace_back(postCode);
10774ae63e71SBonnie Lo }
10784ae63e71SBonnie Lo }
10794ae63e71SBonnie Lo
10804ae63e71SBonnie Lo std::vector<uint8_t> response;
10814ae63e71SBonnie Lo if (resData.size() > maxPostCodeLen)
10824ae63e71SBonnie Lo {
10834ae63e71SBonnie Lo startIndex = resData.size() - maxPostCodeLen;
10844ae63e71SBonnie Lo }
10854ae63e71SBonnie Lo
10864ae63e71SBonnie Lo response.assign(resData.begin() + startIndex, resData.end());
10874ae63e71SBonnie Lo
10884ae63e71SBonnie Lo return ipmi::responseSuccess(response);
10894ae63e71SBonnie Lo }
10904ae63e71SBonnie Lo
1091e7d23d0eSVijay Khemka //----------------------------------------------------------------------
10921d4a0697SVijay Khemka // Set Boot Order (CMD_OEM_SET_BOOT_ORDER)
10931d4a0697SVijay Khemka //----------------------------------------------------------------------
1094f0cf6658SJayashree-D ipmi::RspType<std::vector<uint8_t>>
ipmiOemSetBootOrder(ipmi::Context::ptr ctx,std::vector<uint8_t> bootSeq)10957bb4592aSDelphine CC Chiu ipmiOemSetBootOrder(ipmi::Context::ptr ctx, std::vector<uint8_t> bootSeq)
10961d4a0697SVijay Khemka {
10977bb4592aSDelphine CC Chiu size_t len = bootSeq.size();
10981d4a0697SVijay Khemka
10991d4a0697SVijay Khemka if (len != SIZE_BOOT_ORDER)
11001d4a0697SVijay Khemka {
11011d4a0697SVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
11021d4a0697SVijay Khemka "Invalid Boot order length received");
1103f0cf6658SJayashree-D return ipmi::responseReqDataLenInvalid();
11041d4a0697SVijay Khemka }
11051d4a0697SVijay Khemka
11064ec80567SJayashree Dhanapal std::optional<size_t> hostId = findHost(ctx->hostIdx);
11071d4a0697SVijay Khemka
1108f0cf6658SJayashree-D if (!hostId)
1109f0cf6658SJayashree-D {
1110f0cf6658SJayashree-D phosphor::logging::log<phosphor::logging::level::ERR>(
1111f0cf6658SJayashree-D "Invalid Host Id received");
1112f0cf6658SJayashree-D return ipmi::responseInvalidCommand();
1113f0cf6658SJayashree-D }
1114f0cf6658SJayashree-D auto [bootObjPath, hostName] = ipmi::boot::objPath(*hostId);
1115f0cf6658SJayashree-D
11167bb4592aSDelphine CC Chiu ipmi::boot::setBootOrder(bootObjPath, bootSeq, hostName);
1117f0cf6658SJayashree-D
11187bb4592aSDelphine CC Chiu return ipmi::responseSuccess(bootSeq);
11191d4a0697SVijay Khemka }
11201d4a0697SVijay Khemka
11211d4a0697SVijay Khemka //----------------------------------------------------------------------
1122e7d23d0eSVijay Khemka // Get Boot Order (CMD_OEM_GET_BOOT_ORDER)
1123e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemGetBootOrder(ipmi::Context::ptr ctx)11247bb4592aSDelphine CC Chiu ipmi::RspType<std::vector<uint8_t>> ipmiOemGetBootOrder(ipmi::Context::ptr ctx)
1125e7d23d0eSVijay Khemka {
11267bb4592aSDelphine CC Chiu std::vector<uint8_t> bootSeq;
1127e7d23d0eSVijay Khemka
11284ec80567SJayashree Dhanapal std::optional<size_t> hostId = findHost(ctx->hostIdx);
11291d4a0697SVijay Khemka
1130f0cf6658SJayashree-D if (!hostId)
1131f0cf6658SJayashree-D {
1132f0cf6658SJayashree-D phosphor::logging::log<phosphor::logging::level::ERR>(
1133f0cf6658SJayashree-D "Invalid Host Id received");
1134f0cf6658SJayashree-D return ipmi::responseInvalidCommand();
1135f0cf6658SJayashree-D }
1136f0cf6658SJayashree-D auto [bootObjPath, hostName] = ipmi::boot::objPath(*hostId);
1137f0cf6658SJayashree-D
11387bb4592aSDelphine CC Chiu ipmi::boot::getBootOrder(bootObjPath, bootSeq, hostName);
1139f0cf6658SJayashree-D
11407bb4592aSDelphine CC Chiu return ipmi::responseSuccess(bootSeq);
1141e7d23d0eSVijay Khemka }
1142e7d23d0eSVijay Khemka // Set Machine Config Info (CMD_OEM_SET_MACHINE_CONFIG_INFO)
1143e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemSetMachineCfgInfo(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t,ipmi_data_len_t data_len,ipmi_context_t)1144e39f9393SWilly Tu ipmi_ret_t ipmiOemSetMachineCfgInfo(ipmi_netfn_t, ipmi_cmd_t,
1145e39f9393SWilly Tu ipmi_request_t request, ipmi_response_t,
1146e39f9393SWilly Tu ipmi_data_len_t data_len, ipmi_context_t)
1147e7d23d0eSVijay Khemka {
11481d4a0697SVijay Khemka machineConfigInfo_t* req = reinterpret_cast<machineConfigInfo_t*>(request);
11491d4a0697SVijay Khemka uint8_t len = *data_len;
1150e7d23d0eSVijay Khemka
1151e7d23d0eSVijay Khemka *data_len = 0;
1152e7d23d0eSVijay Khemka
11531d4a0697SVijay Khemka if (len < sizeof(machineConfigInfo_t))
11541d4a0697SVijay Khemka {
11551d4a0697SVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
11561d4a0697SVijay Khemka "Invalid machine configuration length received");
11571d4a0697SVijay Khemka return IPMI_CC_REQ_DATA_LEN_INVALID;
11581d4a0697SVijay Khemka }
11591d4a0697SVijay Khemka
11601d4a0697SVijay Khemka if (req->chassis_type >= sizeof(chassisType) / sizeof(uint8_t*))
11611d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_CHAS_TYPE] = "UNKNOWN";
11621d4a0697SVijay Khemka else
11631d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_CHAS_TYPE] =
11641d4a0697SVijay Khemka chassisType[req->chassis_type];
11651d4a0697SVijay Khemka
11661d4a0697SVijay Khemka if (req->mb_type >= sizeof(mbType) / sizeof(uint8_t*))
11671d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_MB_TYPE] = "UNKNOWN";
11681d4a0697SVijay Khemka else
11691d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_MB_TYPE] = mbType[req->mb_type];
11701d4a0697SVijay Khemka
11711d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_PROC_CNT] = req->proc_cnt;
11721d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_MEM_CNT] = req->mem_cnt;
11731d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_HDD35_CNT] = req->hdd35_cnt;
11741d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_HDD25_CNT] = req->hdd25_cnt;
11751d4a0697SVijay Khemka
11761d4a0697SVijay Khemka if (req->riser_type >= sizeof(riserType) / sizeof(uint8_t*))
11771d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_RSR_TYPE] = "UNKNOWN";
11781d4a0697SVijay Khemka else
11791d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_RSR_TYPE] = riserType[req->riser_type];
11801d4a0697SVijay Khemka
11811d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC] = {};
11821d4a0697SVijay Khemka int i = 0;
11831d4a0697SVijay Khemka if (req->pcie_card_loc & BIT_0)
11841d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT1";
11851d4a0697SVijay Khemka if (req->pcie_card_loc & BIT_1)
11861d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT2";
11871d4a0697SVijay Khemka if (req->pcie_card_loc & BIT_2)
11881d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT3";
11891d4a0697SVijay Khemka if (req->pcie_card_loc & BIT_3)
11901d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT4";
11911d4a0697SVijay Khemka
11921d4a0697SVijay Khemka if (req->slot1_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
11931d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_SLOT1_TYPE] = "UNKNOWN";
11941d4a0697SVijay Khemka else
11951d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_SLOT1_TYPE] =
11961d4a0697SVijay Khemka pcieType[req->slot1_pcie_type];
11971d4a0697SVijay Khemka
11981d4a0697SVijay Khemka if (req->slot2_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
11991d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_SLOT2_TYPE] = "UNKNOWN";
12001d4a0697SVijay Khemka else
12011d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_SLOT2_TYPE] =
12021d4a0697SVijay Khemka pcieType[req->slot2_pcie_type];
12031d4a0697SVijay Khemka
12041d4a0697SVijay Khemka if (req->slot3_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
12051d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_SLOT3_TYPE] = "UNKNOWN";
12061d4a0697SVijay Khemka else
12071d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_SLOT3_TYPE] =
12081d4a0697SVijay Khemka pcieType[req->slot3_pcie_type];
12091d4a0697SVijay Khemka
12101d4a0697SVijay Khemka if (req->slot4_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
12111d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_SLOT4_TYPE] = "UNKNOWN";
12121d4a0697SVijay Khemka else
12131d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_SLOT4_TYPE] =
12141d4a0697SVijay Khemka pcieType[req->slot4_pcie_type];
12151d4a0697SVijay Khemka
12161d4a0697SVijay Khemka oemData[KEY_MC_CONFIG][KEY_MC_AEP_CNT] = req->aep_mem_cnt;
12171d4a0697SVijay Khemka
12181d4a0697SVijay Khemka flushOemData();
12191d4a0697SVijay Khemka
1220e7d23d0eSVijay Khemka return IPMI_CC_OK;
1221e7d23d0eSVijay Khemka }
1222e7d23d0eSVijay Khemka
1223e7d23d0eSVijay Khemka //----------------------------------------------------------------------
1224e7d23d0eSVijay Khemka // Set POST start (CMD_OEM_SET_POST_START)
1225e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemSetPostStart(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t,ipmi_response_t,ipmi_data_len_t data_len,ipmi_context_t)1226e39f9393SWilly Tu ipmi_ret_t ipmiOemSetPostStart(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
1227e39f9393SWilly Tu ipmi_response_t, ipmi_data_len_t data_len,
1228e39f9393SWilly Tu ipmi_context_t)
1229e7d23d0eSVijay Khemka {
1230e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::INFO>("POST Start Event");
1231e7d23d0eSVijay Khemka
12321d4a0697SVijay Khemka /* Do nothing, return success */
1233e7d23d0eSVijay Khemka *data_len = 0;
1234e7d23d0eSVijay Khemka return IPMI_CC_OK;
1235e7d23d0eSVijay Khemka }
1236e7d23d0eSVijay Khemka
1237e7d23d0eSVijay Khemka //----------------------------------------------------------------------
1238e7d23d0eSVijay Khemka // Set POST End (CMD_OEM_SET_POST_END)
1239e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemSetPostEnd(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t,ipmi_response_t,ipmi_data_len_t data_len,ipmi_context_t)1240e39f9393SWilly Tu ipmi_ret_t ipmiOemSetPostEnd(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
1241e39f9393SWilly Tu ipmi_response_t, ipmi_data_len_t data_len,
1242e39f9393SWilly Tu ipmi_context_t)
1243e7d23d0eSVijay Khemka {
12441d4a0697SVijay Khemka struct timespec ts;
1245e7d23d0eSVijay Khemka
1246e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::INFO>("POST End Event");
1247e7d23d0eSVijay Khemka
1248e7d23d0eSVijay Khemka *data_len = 0;
12491d4a0697SVijay Khemka
12501d4a0697SVijay Khemka // Timestamp post end time.
12511d4a0697SVijay Khemka clock_gettime(CLOCK_REALTIME, &ts);
12521d4a0697SVijay Khemka oemData[KEY_TS_SLED] = ts.tv_sec;
12531d4a0697SVijay Khemka flushOemData();
12541d4a0697SVijay Khemka
12551d4a0697SVijay Khemka // Sync time with system
12561d4a0697SVijay Khemka // TODO: Add code for syncing time
12571d4a0697SVijay Khemka
12581d4a0697SVijay Khemka return IPMI_CC_OK;
12591d4a0697SVijay Khemka }
12601d4a0697SVijay Khemka
12611d4a0697SVijay Khemka //----------------------------------------------------------------------
12621d4a0697SVijay Khemka // Set PPIN Info (CMD_OEM_SET_PPIN_INFO)
12631d4a0697SVijay Khemka //----------------------------------------------------------------------
12641d4a0697SVijay Khemka // Inform BMC about PPIN data of 8 bytes for each CPU
12651d4a0697SVijay Khemka //
12661d4a0697SVijay Khemka // Request:
12671d4a0697SVijay Khemka // Byte 1:8 – CPU0 PPIN data
12681d4a0697SVijay Khemka // Optional:
12691d4a0697SVijay Khemka // Byte 9:16 – CPU1 PPIN data
12701d4a0697SVijay Khemka //
12711d4a0697SVijay Khemka // Response:
12721d4a0697SVijay Khemka // Byte 1 – Completion Code
ipmiOemSetPPINInfo(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t,ipmi_data_len_t data_len,ipmi_context_t)1273e39f9393SWilly Tu ipmi_ret_t ipmiOemSetPPINInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1274e39f9393SWilly Tu ipmi_response_t, ipmi_data_len_t data_len,
1275e39f9393SWilly Tu ipmi_context_t)
12761d4a0697SVijay Khemka {
12771d4a0697SVijay Khemka uint8_t* req = reinterpret_cast<uint8_t*>(request);
12781d4a0697SVijay Khemka std::string ppinStr;
12791d4a0697SVijay Khemka int len;
12801d4a0697SVijay Khemka
12811d4a0697SVijay Khemka if (*data_len > SIZE_CPU_PPIN * 2)
12821d4a0697SVijay Khemka len = SIZE_CPU_PPIN * 2;
12831d4a0697SVijay Khemka else
12841d4a0697SVijay Khemka len = *data_len;
12851d4a0697SVijay Khemka *data_len = 0;
12861d4a0697SVijay Khemka
12871d4a0697SVijay Khemka ppinStr = bytesToStr(req, len);
12881d4a0697SVijay Khemka oemData[KEY_PPIN_INFO] = ppinStr.c_str();
12891d4a0697SVijay Khemka flushOemData();
12901d4a0697SVijay Khemka
12911d4a0697SVijay Khemka return IPMI_CC_OK;
12921d4a0697SVijay Khemka }
12931d4a0697SVijay Khemka
12941d4a0697SVijay Khemka //----------------------------------------------------------------------
12951d4a0697SVijay Khemka // Set ADR Trigger (CMD_OEM_SET_ADR_TRIGGER)
12961d4a0697SVijay Khemka //----------------------------------------------------------------------
ipmiOemSetAdrTrigger(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t,ipmi_response_t,ipmi_data_len_t data_len,ipmi_context_t)1297e39f9393SWilly Tu ipmi_ret_t ipmiOemSetAdrTrigger(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
1298e39f9393SWilly Tu ipmi_response_t, ipmi_data_len_t data_len,
1299e39f9393SWilly Tu ipmi_context_t)
13001d4a0697SVijay Khemka {
13011d4a0697SVijay Khemka /* Do nothing, return success */
13021d4a0697SVijay Khemka *data_len = 0;
1303e7d23d0eSVijay Khemka return IPMI_CC_OK;
1304e7d23d0eSVijay Khemka }
1305e7d23d0eSVijay Khemka
1306f2246ce8SVijay Khemka // Helper function to set guid at offset in EEPROM
setGUID(off_t offset,uint8_t * guid)1307e39f9393SWilly Tu [[maybe_unused]] static int setGUID(off_t offset, uint8_t* guid)
1308f2246ce8SVijay Khemka {
1309f2246ce8SVijay Khemka int fd = -1;
1310f2246ce8SVijay Khemka ssize_t len;
1311f2246ce8SVijay Khemka int ret = 0;
1312b2ae88b4Scchoux std::string eepromPath = FRU_EEPROM;
1313b2ae88b4Scchoux
1314b2ae88b4Scchoux // find the eeprom path of MB FRU
1315b2ae88b4Scchoux auto device = getMbFruDevice();
1316b2ae88b4Scchoux if (device)
1317b2ae88b4Scchoux {
1318b2ae88b4Scchoux auto [bus, address] = *device;
1319b2ae88b4Scchoux std::stringstream ss;
1320b2ae88b4Scchoux ss << "/sys/bus/i2c/devices/" << static_cast<int>(bus) << "-"
1321b2ae88b4Scchoux << std::setw(4) << std::setfill('0') << std::hex
1322b2ae88b4Scchoux << static_cast<int>(address) << "/eeprom";
1323b2ae88b4Scchoux eepromPath = ss.str();
1324b2ae88b4Scchoux }
1325f2246ce8SVijay Khemka
1326f2246ce8SVijay Khemka errno = 0;
1327f2246ce8SVijay Khemka
1328f2246ce8SVijay Khemka // Check if file is present
1329b2ae88b4Scchoux if (access(eepromPath.c_str(), F_OK) == -1)
1330f2246ce8SVijay Khemka {
1331b2ae88b4Scchoux std::cerr << "Unable to access: " << eepromPath << std::endl;
1332f2246ce8SVijay Khemka return errno;
1333f2246ce8SVijay Khemka }
1334f2246ce8SVijay Khemka
1335f2246ce8SVijay Khemka // Open the file
1336b2ae88b4Scchoux fd = open(eepromPath.c_str(), O_WRONLY);
1337f2246ce8SVijay Khemka if (fd == -1)
1338f2246ce8SVijay Khemka {
1339b2ae88b4Scchoux std::cerr << "Unable to open: " << eepromPath << std::endl;
1340f2246ce8SVijay Khemka return errno;
1341f2246ce8SVijay Khemka }
1342f2246ce8SVijay Khemka
1343f2246ce8SVijay Khemka // seek to the offset
1344f2246ce8SVijay Khemka lseek(fd, offset, SEEK_SET);
1345f2246ce8SVijay Khemka
1346f2246ce8SVijay Khemka // Write bytes to location
1347f2246ce8SVijay Khemka len = write(fd, guid, GUID_SIZE);
1348f2246ce8SVijay Khemka if (len != GUID_SIZE)
1349f2246ce8SVijay Khemka {
1350f2246ce8SVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
1351f2246ce8SVijay Khemka "GUID write data to EEPROM failed");
1352f2246ce8SVijay Khemka ret = errno;
1353f2246ce8SVijay Khemka }
1354f2246ce8SVijay Khemka
1355f2246ce8SVijay Khemka close(fd);
1356f2246ce8SVijay Khemka return ret;
1357f2246ce8SVijay Khemka }
1358f2246ce8SVijay Khemka
1359f2246ce8SVijay Khemka //----------------------------------------------------------------------
1360f2246ce8SVijay Khemka // Set System GUID (CMD_OEM_SET_SYSTEM_GUID)
1361f2246ce8SVijay Khemka //----------------------------------------------------------------------
13625f8e3435SManikandan Elumalai #if BIC_ENABLED
ipmiOemSetSystemGuid(ipmi::Context::ptr ctx,std::vector<uint8_t> reqData)13633f671273SBonnie Lo ipmi::RspType<> ipmiOemSetSystemGuid(ipmi::Context::ptr ctx,
13645f8e3435SManikandan Elumalai std::vector<uint8_t> reqData)
13655f8e3435SManikandan Elumalai {
13665f8e3435SManikandan Elumalai std::vector<uint8_t> respData;
13675f8e3435SManikandan Elumalai
13685f8e3435SManikandan Elumalai if (reqData.size() != GUID_SIZE) // 16bytes
13695f8e3435SManikandan Elumalai {
13705f8e3435SManikandan Elumalai return ipmi::responseReqDataLenInvalid();
13715f8e3435SManikandan Elumalai }
13725f8e3435SManikandan Elumalai
13735f8e3435SManikandan Elumalai uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
13745f8e3435SManikandan Elumalai
13755f8e3435SManikandan Elumalai if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, reqData, respData))
13765f8e3435SManikandan Elumalai return ipmi::responseUnspecifiedError();
13775f8e3435SManikandan Elumalai
13785f8e3435SManikandan Elumalai return ipmi::responseSuccess();
13795f8e3435SManikandan Elumalai }
13805f8e3435SManikandan Elumalai
13815f8e3435SManikandan Elumalai #else
ipmiOemSetSystemGuid(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t,ipmi_data_len_t data_len,ipmi_context_t)1382d5353caaSPotin Lai ipmi_ret_t ipmiOemSetSystemGuid(ipmi_netfn_t, ipmi_cmd_t,
1383d5353caaSPotin Lai ipmi_request_t request, ipmi_response_t,
1384d5353caaSPotin Lai ipmi_data_len_t data_len, ipmi_context_t)
1385f2246ce8SVijay Khemka {
1386f2246ce8SVijay Khemka uint8_t* req = reinterpret_cast<uint8_t*>(request);
1387f2246ce8SVijay Khemka
1388f2246ce8SVijay Khemka if (*data_len != GUID_SIZE) // 16bytes
1389f2246ce8SVijay Khemka {
1390f2246ce8SVijay Khemka *data_len = 0;
1391f2246ce8SVijay Khemka return IPMI_CC_REQ_DATA_LEN_INVALID;
1392f2246ce8SVijay Khemka }
1393f2246ce8SVijay Khemka
1394f2246ce8SVijay Khemka *data_len = 0;
1395f2246ce8SVijay Khemka
1396f2246ce8SVijay Khemka if (setGUID(OFFSET_SYS_GUID, req))
1397f2246ce8SVijay Khemka {
1398f2246ce8SVijay Khemka return IPMI_CC_UNSPECIFIED_ERROR;
1399f2246ce8SVijay Khemka }
1400f2246ce8SVijay Khemka return IPMI_CC_OK;
1401f2246ce8SVijay Khemka }
14025f8e3435SManikandan Elumalai #endif
1403f2246ce8SVijay Khemka
1404e7d23d0eSVijay Khemka //----------------------------------------------------------------------
1405e7d23d0eSVijay Khemka // Set Bios Flash Info (CMD_OEM_SET_BIOS_FLASH_INFO)
1406e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemSetBiosFlashInfo(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t,ipmi_response_t,ipmi_data_len_t data_len,ipmi_context_t)1407e39f9393SWilly Tu ipmi_ret_t ipmiOemSetBiosFlashInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
1408e39f9393SWilly Tu ipmi_response_t, ipmi_data_len_t data_len,
1409e39f9393SWilly Tu ipmi_context_t)
1410e7d23d0eSVijay Khemka {
14111d4a0697SVijay Khemka /* Do nothing, return success */
1412e7d23d0eSVijay Khemka *data_len = 0;
1413e7d23d0eSVijay Khemka return IPMI_CC_OK;
1414e7d23d0eSVijay Khemka }
1415e7d23d0eSVijay Khemka
1416e7d23d0eSVijay Khemka //----------------------------------------------------------------------
1417e7d23d0eSVijay Khemka // Set PPR (CMD_OEM_SET_PPR)
1418e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemSetPpr(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t,ipmi_data_len_t data_len,ipmi_context_t)1419e39f9393SWilly Tu ipmi_ret_t ipmiOemSetPpr(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1420e39f9393SWilly Tu ipmi_response_t, ipmi_data_len_t data_len,
1421e39f9393SWilly Tu ipmi_context_t)
1422e7d23d0eSVijay Khemka {
1423e7d23d0eSVijay Khemka uint8_t* req = reinterpret_cast<uint8_t*>(request);
14241d4a0697SVijay Khemka uint8_t pprCnt, pprAct, pprIndex;
14251d4a0697SVijay Khemka uint8_t selParam = req[0];
14261d4a0697SVijay Khemka uint8_t len = *data_len;
14271d4a0697SVijay Khemka std::stringstream ss;
14281d4a0697SVijay Khemka std::string str;
1429e7d23d0eSVijay Khemka
1430e7d23d0eSVijay Khemka *data_len = 0;
14311d4a0697SVijay Khemka
14321d4a0697SVijay Khemka switch (selParam)
14331d4a0697SVijay Khemka {
14341d4a0697SVijay Khemka case PPR_ACTION:
14351d4a0697SVijay Khemka if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) ==
14361d4a0697SVijay Khemka oemData[KEY_PPR].end())
14371d4a0697SVijay Khemka return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
14381d4a0697SVijay Khemka
14391d4a0697SVijay Khemka pprCnt = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
14401d4a0697SVijay Khemka if (pprCnt == 0)
14411d4a0697SVijay Khemka return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
14421d4a0697SVijay Khemka
14431d4a0697SVijay Khemka pprAct = req[1];
14441d4a0697SVijay Khemka /* Check if ppr is enabled or disabled */
14451d4a0697SVijay Khemka if (!(pprAct & 0x80))
14461d4a0697SVijay Khemka pprAct = 0;
14471d4a0697SVijay Khemka
14481d4a0697SVijay Khemka oemData[KEY_PPR][KEY_PPR_ACTION] = pprAct;
14491d4a0697SVijay Khemka break;
14501d4a0697SVijay Khemka case PPR_ROW_COUNT:
14511d4a0697SVijay Khemka if (req[1] > 100)
14521d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
14531d4a0697SVijay Khemka
14541d4a0697SVijay Khemka oemData[KEY_PPR][KEY_PPR_ROW_COUNT] = req[1];
14551d4a0697SVijay Khemka break;
14561d4a0697SVijay Khemka case PPR_ROW_ADDR:
14571d4a0697SVijay Khemka pprIndex = req[1];
14581d4a0697SVijay Khemka if (pprIndex > 100)
14591d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
14601d4a0697SVijay Khemka
14611d4a0697SVijay Khemka if (len < PPR_ROW_ADDR_LEN + 1)
14621d4a0697SVijay Khemka {
14631d4a0697SVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
14641d4a0697SVijay Khemka "Invalid PPR Row Address length received");
14651d4a0697SVijay Khemka return IPMI_CC_REQ_DATA_LEN_INVALID;
14661d4a0697SVijay Khemka }
14671d4a0697SVijay Khemka
14681d4a0697SVijay Khemka ss << std::hex;
14691d4a0697SVijay Khemka ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
14701d4a0697SVijay Khemka
14711d4a0697SVijay Khemka oemData[KEY_PPR][ss.str()][KEY_PPR_INDEX] = pprIndex;
14721d4a0697SVijay Khemka
14731d4a0697SVijay Khemka str = bytesToStr(&req[1], PPR_ROW_ADDR_LEN);
14741d4a0697SVijay Khemka oemData[KEY_PPR][ss.str()][KEY_PPR_ROW_ADDR] = str.c_str();
14751d4a0697SVijay Khemka break;
14761d4a0697SVijay Khemka case PPR_HISTORY_DATA:
14771d4a0697SVijay Khemka pprIndex = req[1];
14781d4a0697SVijay Khemka if (pprIndex > 100)
14791d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
14801d4a0697SVijay Khemka
14811d4a0697SVijay Khemka if (len < PPR_HST_DATA_LEN + 1)
14821d4a0697SVijay Khemka {
14831d4a0697SVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
14841d4a0697SVijay Khemka "Invalid PPR history data length received");
14851d4a0697SVijay Khemka return IPMI_CC_REQ_DATA_LEN_INVALID;
14861d4a0697SVijay Khemka }
14871d4a0697SVijay Khemka
14881d4a0697SVijay Khemka ss << std::hex;
14891d4a0697SVijay Khemka ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
14901d4a0697SVijay Khemka
14911d4a0697SVijay Khemka oemData[KEY_PPR][ss.str()][KEY_PPR_INDEX] = pprIndex;
14921d4a0697SVijay Khemka
14931d4a0697SVijay Khemka str = bytesToStr(&req[1], PPR_HST_DATA_LEN);
14941d4a0697SVijay Khemka oemData[KEY_PPR][ss.str()][KEY_PPR_HST_DATA] = str.c_str();
14951d4a0697SVijay Khemka break;
14961d4a0697SVijay Khemka default:
14971d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
14981d4a0697SVijay Khemka break;
14991d4a0697SVijay Khemka }
15001d4a0697SVijay Khemka
15011d4a0697SVijay Khemka flushOemData();
15021d4a0697SVijay Khemka
1503e7d23d0eSVijay Khemka return IPMI_CC_OK;
1504e7d23d0eSVijay Khemka }
1505e7d23d0eSVijay Khemka
1506e7d23d0eSVijay Khemka //----------------------------------------------------------------------
1507e7d23d0eSVijay Khemka // Get PPR (CMD_OEM_GET_PPR)
1508e7d23d0eSVijay Khemka //----------------------------------------------------------------------
ipmiOemGetPpr(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t response,ipmi_data_len_t data_len,ipmi_context_t)1509e39f9393SWilly Tu ipmi_ret_t ipmiOemGetPpr(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1510e39f9393SWilly Tu ipmi_response_t response, ipmi_data_len_t data_len,
1511e39f9393SWilly Tu ipmi_context_t)
1512e7d23d0eSVijay Khemka {
1513e7d23d0eSVijay Khemka uint8_t* req = reinterpret_cast<uint8_t*>(request);
1514e7d23d0eSVijay Khemka uint8_t* res = reinterpret_cast<uint8_t*>(response);
15151d4a0697SVijay Khemka uint8_t pprCnt, pprIndex;
15161d4a0697SVijay Khemka uint8_t selParam = req[0];
15171d4a0697SVijay Khemka std::stringstream ss;
15181d4a0697SVijay Khemka std::string str;
1519e7d23d0eSVijay Khemka
15201d4a0697SVijay Khemka /* Any failure will return zero length data */
15211d4a0697SVijay Khemka *data_len = 0;
15221d4a0697SVijay Khemka
15231d4a0697SVijay Khemka switch (selParam)
15241d4a0697SVijay Khemka {
15251d4a0697SVijay Khemka case PPR_ACTION:
15261d4a0697SVijay Khemka res[0] = 0;
1527e7d23d0eSVijay Khemka *data_len = 1;
1528e7d23d0eSVijay Khemka
15291d4a0697SVijay Khemka if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) !=
15301d4a0697SVijay Khemka oemData[KEY_PPR].end())
15311d4a0697SVijay Khemka {
15321d4a0697SVijay Khemka pprCnt = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
15331d4a0697SVijay Khemka if (pprCnt != 0)
15341d4a0697SVijay Khemka {
15351d4a0697SVijay Khemka if (oemData[KEY_PPR].find(KEY_PPR_ACTION) !=
15361d4a0697SVijay Khemka oemData[KEY_PPR].end())
15371d4a0697SVijay Khemka {
15381d4a0697SVijay Khemka res[0] = oemData[KEY_PPR][KEY_PPR_ACTION];
15391d4a0697SVijay Khemka }
15401d4a0697SVijay Khemka }
15411d4a0697SVijay Khemka }
15421d4a0697SVijay Khemka break;
15431d4a0697SVijay Khemka case PPR_ROW_COUNT:
15441d4a0697SVijay Khemka res[0] = 0;
15451d4a0697SVijay Khemka *data_len = 1;
15461d4a0697SVijay Khemka if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) !=
15471d4a0697SVijay Khemka oemData[KEY_PPR].end())
15481d4a0697SVijay Khemka res[0] = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
15491d4a0697SVijay Khemka break;
15501d4a0697SVijay Khemka case PPR_ROW_ADDR:
15511d4a0697SVijay Khemka pprIndex = req[1];
15521d4a0697SVijay Khemka if (pprIndex > 100)
15531d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
15541d4a0697SVijay Khemka
15551d4a0697SVijay Khemka ss << std::hex;
15561d4a0697SVijay Khemka ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
15571d4a0697SVijay Khemka
15581d4a0697SVijay Khemka if (oemData[KEY_PPR].find(ss.str()) == oemData[KEY_PPR].end())
15591d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
15601d4a0697SVijay Khemka
15611d4a0697SVijay Khemka if (oemData[KEY_PPR][ss.str()].find(KEY_PPR_ROW_ADDR) ==
15621d4a0697SVijay Khemka oemData[KEY_PPR][ss.str()].end())
15631d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
15641d4a0697SVijay Khemka
15651d4a0697SVijay Khemka str = oemData[KEY_PPR][ss.str()][KEY_PPR_ROW_ADDR];
15661d4a0697SVijay Khemka *data_len = strToBytes(str, res);
15671d4a0697SVijay Khemka break;
15681d4a0697SVijay Khemka case PPR_HISTORY_DATA:
15691d4a0697SVijay Khemka pprIndex = req[1];
15701d4a0697SVijay Khemka if (pprIndex > 100)
15711d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
15721d4a0697SVijay Khemka
15731d4a0697SVijay Khemka ss << std::hex;
15741d4a0697SVijay Khemka ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
15751d4a0697SVijay Khemka
15761d4a0697SVijay Khemka if (oemData[KEY_PPR].find(ss.str()) == oemData[KEY_PPR].end())
15771d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
15781d4a0697SVijay Khemka
15791d4a0697SVijay Khemka if (oemData[KEY_PPR][ss.str()].find(KEY_PPR_HST_DATA) ==
15801d4a0697SVijay Khemka oemData[KEY_PPR][ss.str()].end())
15811d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
15821d4a0697SVijay Khemka
15831d4a0697SVijay Khemka str = oemData[KEY_PPR][ss.str()][KEY_PPR_HST_DATA];
15841d4a0697SVijay Khemka *data_len = strToBytes(str, res);
15851d4a0697SVijay Khemka break;
15861d4a0697SVijay Khemka default:
15871d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
15881d4a0697SVijay Khemka break;
15891d4a0697SVijay Khemka }
15901d4a0697SVijay Khemka
15911d4a0697SVijay Khemka return IPMI_CC_OK;
15921d4a0697SVijay Khemka }
15931d4a0697SVijay Khemka
15941d4a0697SVijay Khemka /* FB OEM QC Commands */
15951d4a0697SVijay Khemka
15961d4a0697SVijay Khemka //----------------------------------------------------------------------
15971d4a0697SVijay Khemka // Set Proc Info (CMD_OEM_Q_SET_PROC_INFO)
15981d4a0697SVijay Khemka //----------------------------------------------------------------------
15991d4a0697SVijay Khemka //"Request:
16001d4a0697SVijay Khemka // Byte 1:3 – Manufacturer ID – XXYYZZ h, LSB first
16011d4a0697SVijay Khemka // Byte 4 – Processor Index, 0 base
16021d4a0697SVijay Khemka // Byte 5 – Parameter Selector
16031d4a0697SVijay Khemka // Byte 6..N – Configuration parameter data (see below for Parameters
16041d4a0697SVijay Khemka // of Processor Information)
16051d4a0697SVijay Khemka // Response:
16061d4a0697SVijay Khemka // Byte 1 – Completion code
16071d4a0697SVijay Khemka //
16081d4a0697SVijay Khemka // Parameter#1: (Processor Product Name)
16091d4a0697SVijay Khemka //
16101d4a0697SVijay Khemka // Byte 1..48 –Product name(ASCII code)
16111d4a0697SVijay Khemka // Ex. Intel(R) Xeon(R) CPU E5-2685 v3 @ 2.60GHz
16121d4a0697SVijay Khemka //
16131d4a0697SVijay Khemka // Param#2: Processor Basic Information
16141d4a0697SVijay Khemka // Byte 1 – Core Number
16151d4a0697SVijay Khemka // Byte 2 – Thread Number (LSB)
16161d4a0697SVijay Khemka // Byte 3 – Thread Number (MSB)
16171d4a0697SVijay Khemka // Byte 4 – Processor frequency in MHz (LSB)
16181d4a0697SVijay Khemka // Byte 5 – Processor frequency in MHz (MSB)
16191d4a0697SVijay Khemka // Byte 6..7 – Revision
16201d4a0697SVijay Khemka //
1621d532fecaSKarthikeyan Pasupathi
ipmiOemQSetProcInfo(ipmi::Context::ptr ctx,uint8_t,uint8_t,uint8_t,uint8_t procIndex,uint8_t paramSel,std::vector<uint8_t> request)1622010dee04SPatrick Williams ipmi::RspType<> ipmiOemQSetProcInfo(
1623010dee04SPatrick Williams ipmi::Context::ptr ctx, uint8_t, uint8_t, uint8_t, uint8_t procIndex,
1624010dee04SPatrick Williams uint8_t paramSel, std::vector<uint8_t> request)
16251d4a0697SVijay Khemka {
16261d4a0697SVijay Khemka uint8_t numParam = sizeof(cpuInfoKey) / sizeof(uint8_t*);
16271d4a0697SVijay Khemka std::stringstream ss;
16281d4a0697SVijay Khemka std::string str;
1629d532fecaSKarthikeyan Pasupathi uint8_t len = request.size();
1630d532fecaSKarthikeyan Pasupathi auto hostId = findHost(ctx->hostIdx);
1631d532fecaSKarthikeyan Pasupathi if (!hostId)
1632d532fecaSKarthikeyan Pasupathi {
1633d532fecaSKarthikeyan Pasupathi phosphor::logging::log<phosphor::logging::level::ERR>(
1634d532fecaSKarthikeyan Pasupathi "Invalid Host Id received");
1635d532fecaSKarthikeyan Pasupathi return ipmi::responseInvalidCommand();
1636d532fecaSKarthikeyan Pasupathi }
1637d532fecaSKarthikeyan Pasupathi std::string procInfo = KEY_Q_PROC_INFO + std::to_string(*hostId);
16381d4a0697SVijay Khemka /* check for requested data params */
1639d532fecaSKarthikeyan Pasupathi if (len < 5 || paramSel < 1 || paramSel >= numParam)
16401d4a0697SVijay Khemka {
16411d4a0697SVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
16421d4a0697SVijay Khemka "Invalid parameter received");
1643d532fecaSKarthikeyan Pasupathi return ipmi::responseParmOutOfRange();
16441d4a0697SVijay Khemka }
16451d4a0697SVijay Khemka ss << std::hex;
1646d532fecaSKarthikeyan Pasupathi ss << std::setw(2) << std::setfill('0') << (int)procIndex;
1647d532fecaSKarthikeyan Pasupathi oemData[procInfo][ss.str()][KEY_PROC_INDEX] = procIndex;
1648d532fecaSKarthikeyan Pasupathi str = bytesToStr(request.data(), len);
1649d532fecaSKarthikeyan Pasupathi oemData[procInfo][ss.str()][cpuInfoKey[paramSel]] = str.c_str();
16501d4a0697SVijay Khemka flushOemData();
1651d532fecaSKarthikeyan Pasupathi return ipmi::responseSuccess();
16521d4a0697SVijay Khemka }
16531d4a0697SVijay Khemka
16541d4a0697SVijay Khemka //----------------------------------------------------------------------
16551d4a0697SVijay Khemka // Get Proc Info (CMD_OEM_Q_GET_PROC_INFO)
16561d4a0697SVijay Khemka //----------------------------------------------------------------------
16571d4a0697SVijay Khemka // Request:
16581d4a0697SVijay Khemka // Byte 1:3 – Manufacturer ID – XXYYZZ h, LSB first
16591d4a0697SVijay Khemka // Byte 4 – Processor Index, 0 base
16601d4a0697SVijay Khemka // Byte 5 – Parameter Selector
16611d4a0697SVijay Khemka // Response:
16621d4a0697SVijay Khemka // Byte 1 – Completion code
16631d4a0697SVijay Khemka // Byte 2..N – Configuration Parameter Data (see below for Parameters
16641d4a0697SVijay Khemka // of Processor Information)
16651d4a0697SVijay Khemka //
16661d4a0697SVijay Khemka // Parameter#1: (Processor Product Name)
16671d4a0697SVijay Khemka //
16681d4a0697SVijay Khemka // Byte 1..48 –Product name(ASCII code)
16691d4a0697SVijay Khemka // Ex. Intel(R) Xeon(R) CPU E5-2685 v3 @ 2.60GHz
16701d4a0697SVijay Khemka //
16711d4a0697SVijay Khemka // Param#2: Processor Basic Information
16721d4a0697SVijay Khemka // Byte 1 – Core Number
16731d4a0697SVijay Khemka // Byte 2 – Thread Number (LSB)
16741d4a0697SVijay Khemka // Byte 3 – Thread Number (MSB)
16751d4a0697SVijay Khemka // Byte 4 – Processor frequency in MHz (LSB)
16761d4a0697SVijay Khemka // Byte 5 – Processor frequency in MHz (MSB)
16771d4a0697SVijay Khemka // Byte 6..7 – Revision
16781d4a0697SVijay Khemka //
1679d532fecaSKarthikeyan Pasupathi
1680d532fecaSKarthikeyan Pasupathi ipmi::RspType<std::vector<uint8_t>>
ipmiOemQGetProcInfo(ipmi::Context::ptr ctx,uint8_t,uint8_t,uint8_t,uint8_t procIndex,uint8_t paramSel)1681d532fecaSKarthikeyan Pasupathi ipmiOemQGetProcInfo(ipmi::Context::ptr ctx, uint8_t, uint8_t, uint8_t,
1682d532fecaSKarthikeyan Pasupathi uint8_t procIndex, uint8_t paramSel)
16831d4a0697SVijay Khemka {
16841d4a0697SVijay Khemka uint8_t numParam = sizeof(cpuInfoKey) / sizeof(uint8_t*);
16851d4a0697SVijay Khemka std::stringstream ss;
16861d4a0697SVijay Khemka std::string str;
1687d532fecaSKarthikeyan Pasupathi uint8_t res[MAX_BUF];
1688d532fecaSKarthikeyan Pasupathi auto hostId = findHost(ctx->hostIdx);
1689d532fecaSKarthikeyan Pasupathi if (!hostId)
1690d532fecaSKarthikeyan Pasupathi {
1691d532fecaSKarthikeyan Pasupathi phosphor::logging::log<phosphor::logging::level::ERR>(
1692d532fecaSKarthikeyan Pasupathi "Invalid Host Id received");
1693d532fecaSKarthikeyan Pasupathi return ipmi::responseInvalidCommand();
1694d532fecaSKarthikeyan Pasupathi }
1695d532fecaSKarthikeyan Pasupathi std::string procInfo = KEY_Q_PROC_INFO + std::to_string(*hostId);
1696d532fecaSKarthikeyan Pasupathi if (paramSel < 1 || paramSel >= numParam)
16971d4a0697SVijay Khemka {
16981d4a0697SVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
16991d4a0697SVijay Khemka "Invalid parameter received");
1700d532fecaSKarthikeyan Pasupathi return ipmi::responseParmOutOfRange();
17011d4a0697SVijay Khemka }
17021d4a0697SVijay Khemka ss << std::hex;
1703d532fecaSKarthikeyan Pasupathi ss << std::setw(2) << std::setfill('0') << (int)procIndex;
1704d532fecaSKarthikeyan Pasupathi if (oemData[procInfo].find(ss.str()) == oemData[procInfo].end())
1705d532fecaSKarthikeyan Pasupathi return ipmi::responseCommandNotAvailable();
1706d532fecaSKarthikeyan Pasupathi if (oemData[procInfo][ss.str()].find(cpuInfoKey[paramSel]) ==
1707d532fecaSKarthikeyan Pasupathi oemData[procInfo][ss.str()].end())
1708d532fecaSKarthikeyan Pasupathi return ipmi::responseCommandNotAvailable();
1709d532fecaSKarthikeyan Pasupathi str = oemData[procInfo][ss.str()][cpuInfoKey[paramSel]];
1710d532fecaSKarthikeyan Pasupathi int dataLen = strToBytes(str, res);
1711d532fecaSKarthikeyan Pasupathi std::vector<uint8_t> response(&res[0], &res[dataLen]);
1712d532fecaSKarthikeyan Pasupathi return ipmi::responseSuccess(response);
17131d4a0697SVijay Khemka }
17141d4a0697SVijay Khemka
17151d4a0697SVijay Khemka //----------------------------------------------------------------------
17161d4a0697SVijay Khemka // Set Dimm Info (CMD_OEM_Q_SET_DIMM_INFO)
17171d4a0697SVijay Khemka //----------------------------------------------------------------------
17181d4a0697SVijay Khemka // Request:
17191d4a0697SVijay Khemka // Byte 1:3 – Manufacturer ID – XXYYZZh, LSB first
17201d4a0697SVijay Khemka // Byte 4 – DIMM Index, 0 base
17211d4a0697SVijay Khemka // Byte 5 – Parameter Selector
17221d4a0697SVijay Khemka // Byte 6..N – Configuration parameter data (see below for Parameters
17231d4a0697SVijay Khemka // of DIMM Information)
17241d4a0697SVijay Khemka // Response:
17251d4a0697SVijay Khemka // Byte 1 – Completion code
17261d4a0697SVijay Khemka //
17271d4a0697SVijay Khemka // Param#1 (DIMM Location):
17281d4a0697SVijay Khemka // Byte 1 – DIMM Present
17291d4a0697SVijay Khemka // Byte 1 – DIMM Present
17301d4a0697SVijay Khemka // 01h – Present
17311d4a0697SVijay Khemka // FFh – Not Present
17321d4a0697SVijay Khemka // Byte 2 – Node Number, 0 base
17331d4a0697SVijay Khemka // Byte 3 – Channel Number , 0 base
17341d4a0697SVijay Khemka // Byte 4 – DIMM Number , 0 base
17351d4a0697SVijay Khemka //
17361d4a0697SVijay Khemka // Param#2 (DIMM Type):
17371d4a0697SVijay Khemka // Byte 1 – DIMM Type
17381d4a0697SVijay Khemka // Bit [7:6]
17391d4a0697SVijay Khemka // For DDR3
17401d4a0697SVijay Khemka // 00 – Normal Voltage (1.5V)
17411d4a0697SVijay Khemka // 01 – Ultra Low Voltage (1.25V)
17421d4a0697SVijay Khemka // 10 – Low Voltage (1.35V)
17431d4a0697SVijay Khemka // 11 – Reserved
17441d4a0697SVijay Khemka // For DDR4
17451d4a0697SVijay Khemka // 00 – Reserved
17461d4a0697SVijay Khemka // 01 – Reserved
17471d4a0697SVijay Khemka // 10 – Reserved
17481d4a0697SVijay Khemka // 11 – Normal Voltage (1.2V)
17491d4a0697SVijay Khemka // Bit [5:0]
17501d4a0697SVijay Khemka // 0x00 – SDRAM
17511d4a0697SVijay Khemka // 0x01 – DDR-1 RAM
17521d4a0697SVijay Khemka // 0x02 – Rambus
17531d4a0697SVijay Khemka // 0x03 – DDR-2 RAM
17541d4a0697SVijay Khemka // 0x04 – FBDIMM
17551d4a0697SVijay Khemka // 0x05 – DDR-3 RAM
17561d4a0697SVijay Khemka // 0x06 – DDR-4 RAM
17571d4a0697SVijay Khemka //
17581d4a0697SVijay Khemka // Param#3 (DIMM Speed):
17591d4a0697SVijay Khemka // Byte 1..2 – DIMM speed in MHz, LSB
17601d4a0697SVijay Khemka // Byte 3..6 – DIMM size in Mbytes, LSB
17611d4a0697SVijay Khemka //
17621d4a0697SVijay Khemka // Param#4 (Module Part Number):
17631d4a0697SVijay Khemka // Byte 1..20 –Module Part Number (JEDEC Standard No. 21-C)
17641d4a0697SVijay Khemka //
17651d4a0697SVijay Khemka // Param#5 (Module Serial Number):
17661d4a0697SVijay Khemka // Byte 1..4 –Module Serial Number (JEDEC Standard No. 21-C)
17671d4a0697SVijay Khemka //
17681d4a0697SVijay Khemka // Param#6 (Module Manufacturer ID):
17691d4a0697SVijay Khemka // Byte 1 - Module Manufacturer ID, LSB
17701d4a0697SVijay Khemka // Byte 2 - Module Manufacturer ID, MSB
17711d4a0697SVijay Khemka //
ipmiOemQSetDimmInfo(ipmi::Context::ptr ctx,uint8_t,uint8_t,uint8_t,uint8_t dimmIndex,uint8_t paramSel,std::vector<uint8_t> request)1772010dee04SPatrick Williams ipmi::RspType<> ipmiOemQSetDimmInfo(
1773010dee04SPatrick Williams ipmi::Context::ptr ctx, uint8_t, uint8_t, uint8_t, uint8_t dimmIndex,
1774010dee04SPatrick Williams uint8_t paramSel, std::vector<uint8_t> request)
17751d4a0697SVijay Khemka {
17761d4a0697SVijay Khemka uint8_t numParam = sizeof(dimmInfoKey) / sizeof(uint8_t*);
17771d4a0697SVijay Khemka std::stringstream ss;
17781d4a0697SVijay Khemka std::string str;
177910ff3d86SKarthikeyan Pasupathi uint8_t len = request.size();
178010ff3d86SKarthikeyan Pasupathi std::string dimmType;
178110ff3d86SKarthikeyan Pasupathi readDimmType(dimmType, dimmIndex);
17826d9e9a75SPatrick Williams auto hostId = findHost(ctx->hostIdx);
178310ff3d86SKarthikeyan Pasupathi if (!hostId)
178410ff3d86SKarthikeyan Pasupathi {
178510ff3d86SKarthikeyan Pasupathi phosphor::logging::log<phosphor::logging::level::ERR>(
178610ff3d86SKarthikeyan Pasupathi "Invalid Host Id received");
178710ff3d86SKarthikeyan Pasupathi return ipmi::responseInvalidCommand();
178810ff3d86SKarthikeyan Pasupathi }
17891d4a0697SVijay Khemka
179010ff3d86SKarthikeyan Pasupathi std::string dimmInfo = KEY_Q_DIMM_INFO + std::to_string(*hostId);
17911d4a0697SVijay Khemka
179210ff3d86SKarthikeyan Pasupathi if (len < 3 || paramSel < 1 || paramSel >= numParam)
17931d4a0697SVijay Khemka {
17941d4a0697SVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
17951d4a0697SVijay Khemka "Invalid parameter received");
179610ff3d86SKarthikeyan Pasupathi return ipmi::responseParmOutOfRange();
17971d4a0697SVijay Khemka }
17981d4a0697SVijay Khemka
17991d4a0697SVijay Khemka ss << std::hex;
180010ff3d86SKarthikeyan Pasupathi ss << (int)dimmIndex;
180110ff3d86SKarthikeyan Pasupathi oemData[dimmInfo][ss.str()][KEY_DIMM_INDEX] = dimmIndex;
180210ff3d86SKarthikeyan Pasupathi oemData[dimmInfo][ss.str()][KEY_DIMM_TYPE] = dimmType;
180310ff3d86SKarthikeyan Pasupathi str = bytesToStr(request.data(), len);
180410ff3d86SKarthikeyan Pasupathi oemData[dimmInfo][ss.str()][dimmInfoKey[paramSel]] = str.c_str();
18051d4a0697SVijay Khemka flushOemData();
180610ff3d86SKarthikeyan Pasupathi return ipmi::responseSuccess();
18071d4a0697SVijay Khemka }
18081d4a0697SVijay Khemka
18091d4a0697SVijay Khemka // Get Dimm Info (CMD_OEM_Q_GET_DIMM_INFO)
18101d4a0697SVijay Khemka //----------------------------------------------------------------------
18111d4a0697SVijay Khemka // Request:
18121d4a0697SVijay Khemka // Byte 1:3 – Manufacturer ID – XXYYZZh, LSB first
18131d4a0697SVijay Khemka // Byte 4 – DIMM Index, 0 base
18141d4a0697SVijay Khemka // Byte 5 – Parameter Selector
18151d4a0697SVijay Khemka // Byte 6..N – Configuration parameter data (see below for Parameters
18161d4a0697SVijay Khemka // of DIMM Information)
18171d4a0697SVijay Khemka // Response:
18181d4a0697SVijay Khemka // Byte 1 – Completion code
18191d4a0697SVijay Khemka // Byte 2..N – Configuration Parameter Data (see Table_1213h Parameters
18201d4a0697SVijay Khemka // of DIMM Information)
18211d4a0697SVijay Khemka //
18221d4a0697SVijay Khemka // Param#1 (DIMM Location):
18231d4a0697SVijay Khemka // Byte 1 – DIMM Present
18241d4a0697SVijay Khemka // Byte 1 – DIMM Present
18251d4a0697SVijay Khemka // 01h – Present
18261d4a0697SVijay Khemka // FFh – Not Present
18271d4a0697SVijay Khemka // Byte 2 – Node Number, 0 base
18281d4a0697SVijay Khemka // Byte 3 – Channel Number , 0 base
18291d4a0697SVijay Khemka // Byte 4 – DIMM Number , 0 base
18301d4a0697SVijay Khemka //
18311d4a0697SVijay Khemka // Param#2 (DIMM Type):
18321d4a0697SVijay Khemka // Byte 1 – DIMM Type
18331d4a0697SVijay Khemka // Bit [7:6]
18341d4a0697SVijay Khemka // For DDR3
18351d4a0697SVijay Khemka // 00 – Normal Voltage (1.5V)
18361d4a0697SVijay Khemka // 01 – Ultra Low Voltage (1.25V)
18371d4a0697SVijay Khemka // 10 – Low Voltage (1.35V)
18381d4a0697SVijay Khemka // 11 – Reserved
18391d4a0697SVijay Khemka // For DDR4
18401d4a0697SVijay Khemka // 00 – Reserved
18411d4a0697SVijay Khemka // 01 – Reserved
18421d4a0697SVijay Khemka // 10 – Reserved
18431d4a0697SVijay Khemka // 11 – Normal Voltage (1.2V)
18441d4a0697SVijay Khemka // Bit [5:0]
18451d4a0697SVijay Khemka // 0x00 – SDRAM
18461d4a0697SVijay Khemka // 0x01 – DDR-1 RAM
18471d4a0697SVijay Khemka // 0x02 – Rambus
18481d4a0697SVijay Khemka // 0x03 – DDR-2 RAM
18491d4a0697SVijay Khemka // 0x04 – FBDIMM
18501d4a0697SVijay Khemka // 0x05 – DDR-3 RAM
18511d4a0697SVijay Khemka // 0x06 – DDR-4 RAM
18521d4a0697SVijay Khemka //
18531d4a0697SVijay Khemka // Param#3 (DIMM Speed):
18541d4a0697SVijay Khemka // Byte 1..2 – DIMM speed in MHz, LSB
18551d4a0697SVijay Khemka // Byte 3..6 – DIMM size in Mbytes, LSB
18561d4a0697SVijay Khemka //
18571d4a0697SVijay Khemka // Param#4 (Module Part Number):
18581d4a0697SVijay Khemka // Byte 1..20 –Module Part Number (JEDEC Standard No. 21-C)
18591d4a0697SVijay Khemka //
18601d4a0697SVijay Khemka // Param#5 (Module Serial Number):
18611d4a0697SVijay Khemka // Byte 1..4 –Module Serial Number (JEDEC Standard No. 21-C)
18621d4a0697SVijay Khemka //
18631d4a0697SVijay Khemka // Param#6 (Module Manufacturer ID):
18641d4a0697SVijay Khemka // Byte 1 - Module Manufacturer ID, LSB
18651d4a0697SVijay Khemka // Byte 2 - Module Manufacturer ID, MSB
18661d4a0697SVijay Khemka //
186710ff3d86SKarthikeyan Pasupathi ipmi::RspType<std::vector<uint8_t>>
ipmiOemQGetDimmInfo(ipmi::Context::ptr ctx,uint8_t,uint8_t,uint8_t,uint8_t dimmIndex,uint8_t paramSel)186810ff3d86SKarthikeyan Pasupathi ipmiOemQGetDimmInfo(ipmi::Context::ptr ctx, uint8_t, uint8_t, uint8_t,
186910ff3d86SKarthikeyan Pasupathi uint8_t dimmIndex, uint8_t paramSel)
18701d4a0697SVijay Khemka {
18711d4a0697SVijay Khemka uint8_t numParam = sizeof(dimmInfoKey) / sizeof(uint8_t*);
187210ff3d86SKarthikeyan Pasupathi uint8_t res[MAX_BUF];
18731d4a0697SVijay Khemka std::stringstream ss;
18741d4a0697SVijay Khemka std::string str;
187510ff3d86SKarthikeyan Pasupathi std::string dimmType;
187610ff3d86SKarthikeyan Pasupathi readDimmType(dimmType, dimmIndex);
18776d9e9a75SPatrick Williams auto hostId = findHost(ctx->hostIdx);
187810ff3d86SKarthikeyan Pasupathi if (!hostId)
187910ff3d86SKarthikeyan Pasupathi {
188010ff3d86SKarthikeyan Pasupathi phosphor::logging::log<phosphor::logging::level::ERR>(
188110ff3d86SKarthikeyan Pasupathi "Invalid Host Id received");
188210ff3d86SKarthikeyan Pasupathi return ipmi::responseInvalidCommand();
188310ff3d86SKarthikeyan Pasupathi }
188410ff3d86SKarthikeyan Pasupathi std::string dimmInfo = KEY_Q_DIMM_INFO + std::to_string(*hostId);
18851d4a0697SVijay Khemka
188610ff3d86SKarthikeyan Pasupathi if (paramSel < 1 || paramSel >= numParam)
18871d4a0697SVijay Khemka {
18881d4a0697SVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
18891d4a0697SVijay Khemka "Invalid parameter received");
189010ff3d86SKarthikeyan Pasupathi return ipmi::responseParmOutOfRange();
18911d4a0697SVijay Khemka }
18921d4a0697SVijay Khemka ss << std::hex;
189310ff3d86SKarthikeyan Pasupathi ss << (int)dimmIndex;
189410ff3d86SKarthikeyan Pasupathi oemData[dimmInfo][ss.str()][KEY_DIMM_TYPE] = dimmType;
189510ff3d86SKarthikeyan Pasupathi if (oemData[dimmInfo].find(ss.str()) == oemData[dimmInfo].end())
189610ff3d86SKarthikeyan Pasupathi return ipmi::responseCommandNotAvailable();
189710ff3d86SKarthikeyan Pasupathi if (oemData[dimmInfo][ss.str()].find(dimmInfoKey[paramSel]) ==
189810ff3d86SKarthikeyan Pasupathi oemData[dimmInfo][ss.str()].end())
189910ff3d86SKarthikeyan Pasupathi return ipmi::responseCommandNotAvailable();
190010ff3d86SKarthikeyan Pasupathi str = oemData[dimmInfo][ss.str()][dimmInfoKey[paramSel]];
190110ff3d86SKarthikeyan Pasupathi int data_length = strToBytes(str, res);
190210ff3d86SKarthikeyan Pasupathi std::vector<uint8_t> response(&res[0], &res[data_length]);
190310ff3d86SKarthikeyan Pasupathi return ipmi::responseSuccess(response);
19041d4a0697SVijay Khemka }
19051d4a0697SVijay Khemka
19061d4a0697SVijay Khemka //----------------------------------------------------------------------
19071d4a0697SVijay Khemka // Set Drive Info (CMD_OEM_Q_SET_DRIVE_INFO)
19081d4a0697SVijay Khemka //----------------------------------------------------------------------
19091d4a0697SVijay Khemka // BIOS issue this command to provide HDD information to BMC.
19101d4a0697SVijay Khemka //
19111d4a0697SVijay Khemka // BIOS just can get information by standard ATA / SMART command for
19121d4a0697SVijay Khemka // OB SATA controller.
19131d4a0697SVijay Khemka // BIOS can get
19141d4a0697SVijay Khemka // 1. Serial Number
19151d4a0697SVijay Khemka // 2. Model Name
19161d4a0697SVijay Khemka // 3. HDD FW Version
19171d4a0697SVijay Khemka // 4. HDD Capacity
19181d4a0697SVijay Khemka // 5. HDD WWN
19191d4a0697SVijay Khemka //
19201d4a0697SVijay Khemka // Use Get HDD info Param #5 to know the MAX HDD info index.
19211d4a0697SVijay Khemka //
19221d4a0697SVijay Khemka // Request:
19231d4a0697SVijay Khemka // Byte 1:3 – Quanta Manufacturer ID – 001C4Ch, LSB first
19241d4a0697SVijay Khemka // Byte 4 –
19251d4a0697SVijay Khemka // [7:4] Reserved
19261d4a0697SVijay Khemka // [3:0] HDD Controller Type
19271d4a0697SVijay Khemka // 0x00 – BIOS
19281d4a0697SVijay Khemka // 0x01 – Expander
19291d4a0697SVijay Khemka // 0x02 – LSI
19301d4a0697SVijay Khemka // Byte 5 – HDD Info Index, 0 base
19311d4a0697SVijay Khemka // Byte 6 – Parameter Selector
19321d4a0697SVijay Khemka // Byte 7..N – Configuration parameter data (see Table_1415h Parameters of HDD
19331d4a0697SVijay Khemka // Information)
19341d4a0697SVijay Khemka //
19351d4a0697SVijay Khemka // Response:
19361d4a0697SVijay Khemka // Byte 1 – Completion Code
19371d4a0697SVijay Khemka //
19381d4a0697SVijay Khemka // Param#0 (HDD Location):
19391d4a0697SVijay Khemka // Byte 1 – Controller
19401d4a0697SVijay Khemka // [7:3] Device Number
19411d4a0697SVijay Khemka // [2:0] Function Number
19421d4a0697SVijay Khemka // For Intel C610 series (Wellsburg)
19431d4a0697SVijay Khemka // D31:F2 (0xFA) – SATA control 1
19441d4a0697SVijay Khemka // D31:F5 (0xFD) – SATA control 2
19451d4a0697SVijay Khemka // D17:F4 (0x8C) – sSata control
19461d4a0697SVijay Khemka // Byte 2 – Port Number
19471d4a0697SVijay Khemka // Byte 3 – Location (0xFF: No HDD Present)
19481d4a0697SVijay Khemka // BIOS default set Byte 3 to 0xFF, if No HDD Present. And then skip send param
19491d4a0697SVijay Khemka // #1~4, #6, #7 to BMC (still send param #5) BIOS default set Byte 3 to 0, if
19501d4a0697SVijay Khemka // the HDD present. BMC or other people who know the HDD location has
19511d4a0697SVijay Khemka // responsibility for update Location info
19521d4a0697SVijay Khemka //
19531d4a0697SVijay Khemka // Param#1 (Serial Number):
19541d4a0697SVijay Khemka // Bytes 1..33: HDD Serial Number
19551d4a0697SVijay Khemka //
19561d4a0697SVijay Khemka // Param#2 (Model Name):
19571d4a0697SVijay Khemka // Byte 1..33 – HDD Model Name
19581d4a0697SVijay Khemka //
19591d4a0697SVijay Khemka // Param#3 (HDD FW Version):
19601d4a0697SVijay Khemka // Byte 1..17 –HDD FW version
19611d4a0697SVijay Khemka //
19621d4a0697SVijay Khemka // Param#4 (Capacity):
19631d4a0697SVijay Khemka // Byte 1..4 –HDD Block Size, LSB
19641d4a0697SVijay Khemka // Byte 5..12 - HDD Block Number, LSB
19651d4a0697SVijay Khemka // HDD Capacity = HDD Block size * HDD BLock number (Unit Byte)
19661d4a0697SVijay Khemka //
19671d4a0697SVijay Khemka // Param#5 (Max HDD Quantity):
19681d4a0697SVijay Khemka // Byte 1 - Max HDD Quantity
19691d4a0697SVijay Khemka // Max supported port numbers in this PCH
19701d4a0697SVijay Khemka //
19711d4a0697SVijay Khemka // Param#6 (HDD Type)
19721d4a0697SVijay Khemka // Byte 1 – HDD Type
19731d4a0697SVijay Khemka // 0h – Reserved
19741d4a0697SVijay Khemka // 1h – SAS
19751d4a0697SVijay Khemka // 2h – SATA
19761d4a0697SVijay Khemka // 3h – PCIE SSD (NVME)
19771d4a0697SVijay Khemka //
19781d4a0697SVijay Khemka // Param#7 (HDD WWN)
19791d4a0697SVijay Khemka // Data 1...8: HDD World Wide Name, LSB
19801d4a0697SVijay Khemka //
ipmiOemQSetDriveInfo(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t,ipmi_data_len_t data_len,ipmi_context_t)1981e39f9393SWilly Tu ipmi_ret_t ipmiOemQSetDriveInfo(ipmi_netfn_t, ipmi_cmd_t,
1982e39f9393SWilly Tu ipmi_request_t request, ipmi_response_t,
1983e39f9393SWilly Tu ipmi_data_len_t data_len, ipmi_context_t)
19841d4a0697SVijay Khemka {
19851d4a0697SVijay Khemka qDriveInfo_t* req = reinterpret_cast<qDriveInfo_t*>(request);
19861d4a0697SVijay Khemka uint8_t numParam = sizeof(driveInfoKey) / sizeof(uint8_t*);
19871d4a0697SVijay Khemka uint8_t ctrlType = req->hddCtrlType & 0x0f;
19881d4a0697SVijay Khemka std::stringstream ss;
19891d4a0697SVijay Khemka std::string str;
19901d4a0697SVijay Khemka uint8_t len = *data_len;
19911d4a0697SVijay Khemka
19921d4a0697SVijay Khemka *data_len = 0;
19931d4a0697SVijay Khemka
19941d4a0697SVijay Khemka /* check for requested data params */
19951d4a0697SVijay Khemka if (len < 6 || req->paramSel < 1 || req->paramSel >= numParam ||
19961d4a0697SVijay Khemka ctrlType > 2)
19971d4a0697SVijay Khemka {
19981d4a0697SVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
19991d4a0697SVijay Khemka "Invalid parameter received");
20001d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
20011d4a0697SVijay Khemka }
20021d4a0697SVijay Khemka
20031d4a0697SVijay Khemka len = len - 6; // Get Actual data length
20041d4a0697SVijay Khemka
20051d4a0697SVijay Khemka ss << std::hex;
20061d4a0697SVijay Khemka ss << std::setw(2) << std::setfill('0') << (int)req->hddIndex;
20071d4a0697SVijay Khemka oemData[KEY_Q_DRIVE_INFO][KEY_HDD_CTRL_TYPE] = req->hddCtrlType;
20081d4a0697SVijay Khemka oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()][KEY_HDD_INDEX] =
20091d4a0697SVijay Khemka req->hddIndex;
20101d4a0697SVijay Khemka
20111d4a0697SVijay Khemka str = bytesToStr(req->data, len);
20121d4a0697SVijay Khemka oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()]
20131d4a0697SVijay Khemka [driveInfoKey[req->paramSel]] = str.c_str();
20141d4a0697SVijay Khemka flushOemData();
20151d4a0697SVijay Khemka
20161d4a0697SVijay Khemka return IPMI_CC_OK;
20171d4a0697SVijay Khemka }
20181d4a0697SVijay Khemka
20191d4a0697SVijay Khemka //----------------------------------------------------------------------
20201d4a0697SVijay Khemka // Get Drive Info (CMD_OEM_Q_GET_DRIVE_INFO)
20211d4a0697SVijay Khemka //----------------------------------------------------------------------
20221d4a0697SVijay Khemka // BMC needs to check HDD presented or not first. If NOT presented, return
20231d4a0697SVijay Khemka // completion code 0xD5.
20241d4a0697SVijay Khemka //
20251d4a0697SVijay Khemka // Request:
20261d4a0697SVijay Khemka // Byte 1:3 – Quanta Manufacturer ID – 001C4Ch, LSB first
20271d4a0697SVijay Khemka // Byte 4 –
20281d4a0697SVijay Khemka //[7:4] Reserved
20291d4a0697SVijay Khemka //[3:0] HDD Controller Type
20301d4a0697SVijay Khemka // 0x00 – BIOS
20311d4a0697SVijay Khemka // 0x01 – Expander
20321d4a0697SVijay Khemka // 0x02 – LSI
20331d4a0697SVijay Khemka // Byte 5 – HDD Index, 0 base
20341d4a0697SVijay Khemka // Byte 6 – Parameter Selector (See Above Set HDD Information)
20351d4a0697SVijay Khemka // Response:
20361d4a0697SVijay Khemka // Byte 1 – Completion Code
20371d4a0697SVijay Khemka // 0xD5 – Not support in current status (HDD Not Present)
20381d4a0697SVijay Khemka // Byte 2..N – Configuration parameter data (see Table_1415h Parameters of HDD
20391d4a0697SVijay Khemka // Information)
20401d4a0697SVijay Khemka //
ipmiOemQGetDriveInfo(ipmi_netfn_t,ipmi_cmd_t,ipmi_request_t request,ipmi_response_t response,ipmi_data_len_t data_len,ipmi_context_t)2041010dee04SPatrick Williams ipmi_ret_t ipmiOemQGetDriveInfo(
2042010dee04SPatrick Williams ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request, ipmi_response_t response,
2043e39f9393SWilly Tu ipmi_data_len_t data_len, ipmi_context_t)
20441d4a0697SVijay Khemka {
20451d4a0697SVijay Khemka qDriveInfo_t* req = reinterpret_cast<qDriveInfo_t*>(request);
20461d4a0697SVijay Khemka uint8_t numParam = sizeof(driveInfoKey) / sizeof(uint8_t*);
20471d4a0697SVijay Khemka uint8_t* res = reinterpret_cast<uint8_t*>(response);
20481d4a0697SVijay Khemka uint8_t ctrlType = req->hddCtrlType & 0x0f;
20491d4a0697SVijay Khemka std::stringstream ss;
20501d4a0697SVijay Khemka std::string str;
20511d4a0697SVijay Khemka
20521d4a0697SVijay Khemka *data_len = 0;
20531d4a0697SVijay Khemka
20541d4a0697SVijay Khemka /* check for requested data params */
20551d4a0697SVijay Khemka if (req->paramSel < 1 || req->paramSel >= numParam || ctrlType > 2)
20561d4a0697SVijay Khemka {
20571d4a0697SVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(
20581d4a0697SVijay Khemka "Invalid parameter received");
20591d4a0697SVijay Khemka return IPMI_CC_PARM_OUT_OF_RANGE;
20601d4a0697SVijay Khemka }
20611d4a0697SVijay Khemka
20621d4a0697SVijay Khemka if (oemData[KEY_Q_DRIVE_INFO].find(ctrlTypeKey[ctrlType]) ==
20631d4a0697SVijay Khemka oemData[KEY_Q_DRIVE_INFO].end())
20641d4a0697SVijay Khemka return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
20651d4a0697SVijay Khemka
20661d4a0697SVijay Khemka ss << std::hex;
20671d4a0697SVijay Khemka ss << std::setw(2) << std::setfill('0') << (int)req->hddIndex;
20681d4a0697SVijay Khemka
20691d4a0697SVijay Khemka if (oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]].find(ss.str()) ==
20701d4a0697SVijay Khemka oemData[KEY_Q_DRIVE_INFO].end())
20711d4a0697SVijay Khemka return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
20721d4a0697SVijay Khemka
20731d4a0697SVijay Khemka if (oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()].find(
20741d4a0697SVijay Khemka dimmInfoKey[req->paramSel]) ==
20751d4a0697SVijay Khemka oemData[KEY_Q_DRIVE_INFO][ss.str()].end())
20761d4a0697SVijay Khemka return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
20771d4a0697SVijay Khemka
20781d4a0697SVijay Khemka str = oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()]
20791d4a0697SVijay Khemka [dimmInfoKey[req->paramSel]];
20801d4a0697SVijay Khemka *data_len = strToBytes(str, res);
20811d4a0697SVijay Khemka
2082e7d23d0eSVijay Khemka return IPMI_CC_OK;
2083e7d23d0eSVijay Khemka }
2084e7d23d0eSVijay Khemka
2085e4d6fe74SLogananth Sundararaj /* Helper function for sending DCMI commands to ME/BIC and
2086e4d6fe74SLogananth Sundararaj * getting response back
2087e4d6fe74SLogananth Sundararaj */
2088e4d6fe74SLogananth Sundararaj ipmi::RspType<std::vector<uint8_t>>
sendDCMICmd(ipmi::Context::ptr ctx,uint8_t cmd,std::vector<uint8_t> & cmdData)2089e4d6fe74SLogananth Sundararaj sendDCMICmd([[maybe_unused]] ipmi::Context::ptr ctx,
2090e4d6fe74SLogananth Sundararaj [[maybe_unused]] uint8_t cmd, std::vector<uint8_t>& cmdData)
2091dd14c0f7SVijay Khemka {
2092dd14c0f7SVijay Khemka std::vector<uint8_t> respData;
2093dd14c0f7SVijay Khemka
2094e4d6fe74SLogananth Sundararaj #if BIC_ENABLED
2095e4d6fe74SLogananth Sundararaj
2096e4d6fe74SLogananth Sundararaj uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
2097e4d6fe74SLogananth Sundararaj
2098e4d6fe74SLogananth Sundararaj if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, cmdData, respData))
2099e4d6fe74SLogananth Sundararaj {
2100e4d6fe74SLogananth Sundararaj return ipmi::responseUnspecifiedError();
2101e4d6fe74SLogananth Sundararaj }
2102e4d6fe74SLogananth Sundararaj
2103e4d6fe74SLogananth Sundararaj #else
2104e4d6fe74SLogananth Sundararaj
2105dd14c0f7SVijay Khemka /* Add group id as first byte to request for ME command */
2106dd14c0f7SVijay Khemka cmdData.insert(cmdData.begin(), groupDCMI);
2107dd14c0f7SVijay Khemka
2108dd14c0f7SVijay Khemka if (sendMeCmd(ipmi::netFnGroup, cmd, cmdData, respData))
2109e4d6fe74SLogananth Sundararaj {
2110dd14c0f7SVijay Khemka return ipmi::responseUnspecifiedError();
2111e4d6fe74SLogananth Sundararaj }
2112dd14c0f7SVijay Khemka
2113dd14c0f7SVijay Khemka /* Remove group id as first byte as it will be added by IPMID */
2114dd14c0f7SVijay Khemka respData.erase(respData.begin());
2115dd14c0f7SVijay Khemka
2116e4d6fe74SLogananth Sundararaj #endif
2117e4d6fe74SLogananth Sundararaj
2118dd14c0f7SVijay Khemka return ipmi::responseSuccess(std::move(respData));
2119dd14c0f7SVijay Khemka }
2120dd14c0f7SVijay Khemka
2121dd14c0f7SVijay Khemka /* DCMI Command handellers. */
2122dd14c0f7SVijay Khemka
ipmiOemDCMIGetPowerReading(ipmi::Context::ptr ctx,std::vector<uint8_t> reqData)2123010dee04SPatrick Williams ipmi::RspType<std::vector<uint8_t>> ipmiOemDCMIGetPowerReading(
2124010dee04SPatrick Williams ipmi::Context::ptr ctx, std::vector<uint8_t> reqData)
2125dd14c0f7SVijay Khemka {
2126e4d6fe74SLogananth Sundararaj return sendDCMICmd(ctx, ipmi::dcmi::cmdGetPowerReading, reqData);
2127dd14c0f7SVijay Khemka }
2128dd14c0f7SVijay Khemka
ipmiOemDCMIGetPowerLimit(ipmi::Context::ptr ctx,std::vector<uint8_t> reqData)2129010dee04SPatrick Williams ipmi::RspType<std::vector<uint8_t>> ipmiOemDCMIGetPowerLimit(
2130010dee04SPatrick Williams ipmi::Context::ptr ctx, std::vector<uint8_t> reqData)
2131dd14c0f7SVijay Khemka {
2132e4d6fe74SLogananth Sundararaj return sendDCMICmd(ctx, ipmi::dcmi::cmdGetPowerLimit, reqData);
2133dd14c0f7SVijay Khemka }
2134dd14c0f7SVijay Khemka
ipmiOemDCMISetPowerLimit(ipmi::Context::ptr ctx,std::vector<uint8_t> reqData)2135010dee04SPatrick Williams ipmi::RspType<std::vector<uint8_t>> ipmiOemDCMISetPowerLimit(
2136010dee04SPatrick Williams ipmi::Context::ptr ctx, std::vector<uint8_t> reqData)
2137dd14c0f7SVijay Khemka {
2138e4d6fe74SLogananth Sundararaj return sendDCMICmd(ctx, ipmi::dcmi::cmdSetPowerLimit, reqData);
2139dd14c0f7SVijay Khemka }
2140dd14c0f7SVijay Khemka
ipmiOemDCMIApplyPowerLimit(ipmi::Context::ptr ctx,std::vector<uint8_t> reqData)2141010dee04SPatrick Williams ipmi::RspType<std::vector<uint8_t>> ipmiOemDCMIApplyPowerLimit(
2142010dee04SPatrick Williams ipmi::Context::ptr ctx, std::vector<uint8_t> reqData)
2143dd14c0f7SVijay Khemka {
2144e4d6fe74SLogananth Sundararaj return sendDCMICmd(ctx, ipmi::dcmi::cmdActDeactivatePwrLimit, reqData);
2145dd14c0f7SVijay Khemka }
2146dd14c0f7SVijay Khemka
214799d42b6eSCosmo Chou // Https Boot related functions
ipmiOemGetHttpsData(ipmi::Context::ptr ctx,std::vector<uint8_t> reqData)2148010dee04SPatrick Williams ipmi::RspType<std::vector<uint8_t>> ipmiOemGetHttpsData(
2149010dee04SPatrick Williams [[maybe_unused]] ipmi::Context::ptr ctx, std::vector<uint8_t> reqData)
215099d42b6eSCosmo Chou {
215199d42b6eSCosmo Chou if (reqData.size() < sizeof(HttpsDataReq))
215299d42b6eSCosmo Chou return ipmi::responseReqDataLenInvalid();
215399d42b6eSCosmo Chou
215499d42b6eSCosmo Chou const auto* pReq = reinterpret_cast<const HttpsDataReq*>(reqData.data());
215599d42b6eSCosmo Chou std::error_code ec;
215699d42b6eSCosmo Chou auto fileSize = std::filesystem::file_size(certPath, ec);
215799d42b6eSCosmo Chou if (ec)
215899d42b6eSCosmo Chou return ipmi::responseUnspecifiedError();
215999d42b6eSCosmo Chou
216099d42b6eSCosmo Chou if (pReq->offset >= fileSize)
216199d42b6eSCosmo Chou return ipmi::responseInvalidFieldRequest();
216299d42b6eSCosmo Chou
216399d42b6eSCosmo Chou std::ifstream file(certPath, std::ios::binary);
216499d42b6eSCosmo Chou if (!file)
216599d42b6eSCosmo Chou return ipmi::responseUnspecifiedError();
216699d42b6eSCosmo Chou
216799d42b6eSCosmo Chou auto readLen = std::min<uint16_t>(pReq->length, fileSize - pReq->offset);
216899d42b6eSCosmo Chou std::vector<uint8_t> resData(readLen + 1);
216999d42b6eSCosmo Chou resData[0] = readLen;
217099d42b6eSCosmo Chou file.seekg(pReq->offset);
217199d42b6eSCosmo Chou file.read(reinterpret_cast<char*>(resData.data() + 1), readLen);
217299d42b6eSCosmo Chou
217399d42b6eSCosmo Chou return ipmi::responseSuccess(resData);
217499d42b6eSCosmo Chou }
217599d42b6eSCosmo Chou
ipmiOemGetHttpsAttr(ipmi::Context::ptr ctx,std::vector<uint8_t> reqData)2176010dee04SPatrick Williams ipmi::RspType<std::vector<uint8_t>> ipmiOemGetHttpsAttr(
2177010dee04SPatrick Williams [[maybe_unused]] ipmi::Context::ptr ctx, std::vector<uint8_t> reqData)
217899d42b6eSCosmo Chou {
217999d42b6eSCosmo Chou if (reqData.size() < sizeof(HttpsBootAttr))
218099d42b6eSCosmo Chou return ipmi::responseReqDataLenInvalid();
218199d42b6eSCosmo Chou
218299d42b6eSCosmo Chou std::vector<uint8_t> resData;
218399d42b6eSCosmo Chou
218499d42b6eSCosmo Chou switch (static_cast<HttpsBootAttr>(reqData[0]))
218599d42b6eSCosmo Chou {
218699d42b6eSCosmo Chou case HttpsBootAttr::certSize:
218799d42b6eSCosmo Chou {
218899d42b6eSCosmo Chou std::error_code ec;
218999d42b6eSCosmo Chou auto fileSize = std::filesystem::file_size(certPath, ec);
219099d42b6eSCosmo Chou if (ec || fileSize > std::numeric_limits<uint16_t>::max())
219199d42b6eSCosmo Chou return ipmi::responseUnspecifiedError();
219299d42b6eSCosmo Chou
219399d42b6eSCosmo Chou uint16_t size = static_cast<uint16_t>(fileSize);
219499d42b6eSCosmo Chou resData.resize(sizeof(uint16_t));
219599d42b6eSCosmo Chou std::memcpy(resData.data(), &size, sizeof(uint16_t));
219699d42b6eSCosmo Chou break;
219799d42b6eSCosmo Chou }
219899d42b6eSCosmo Chou case HttpsBootAttr::certCrc:
219999d42b6eSCosmo Chou {
220099d42b6eSCosmo Chou std::ifstream file(certPath, std::ios::binary);
220199d42b6eSCosmo Chou if (!file)
220299d42b6eSCosmo Chou return ipmi::responseUnspecifiedError();
220399d42b6eSCosmo Chou
220499d42b6eSCosmo Chou boost::crc_32_type result;
220599d42b6eSCosmo Chou char data[1024];
220699d42b6eSCosmo Chou while (file.read(data, sizeof(data)))
220799d42b6eSCosmo Chou result.process_bytes(data, file.gcount());
220899d42b6eSCosmo Chou if (file.gcount() > 0)
220999d42b6eSCosmo Chou result.process_bytes(data, file.gcount());
221099d42b6eSCosmo Chou
221199d42b6eSCosmo Chou uint32_t crc = result.checksum();
221299d42b6eSCosmo Chou resData.resize(sizeof(uint32_t));
221399d42b6eSCosmo Chou std::memcpy(resData.data(), &crc, sizeof(uint32_t));
221499d42b6eSCosmo Chou break;
221599d42b6eSCosmo Chou }
221699d42b6eSCosmo Chou default:
221799d42b6eSCosmo Chou return ipmi::responseInvalidFieldRequest();
221899d42b6eSCosmo Chou }
221999d42b6eSCosmo Chou
222099d42b6eSCosmo Chou return ipmi::responseSuccess(resData);
222199d42b6eSCosmo Chou }
222299d42b6eSCosmo Chou
22237ab87bbbSCosmo Chou // OEM Crashdump related functions
setDumpState(CrdState & currState,CrdState newState)22247ab87bbbSCosmo Chou static ipmi_ret_t setDumpState(CrdState& currState, CrdState newState)
22257ab87bbbSCosmo Chou {
22267ab87bbbSCosmo Chou switch (newState)
22277ab87bbbSCosmo Chou {
22287ab87bbbSCosmo Chou case CrdState::waitData:
22297ab87bbbSCosmo Chou if (currState == CrdState::packing)
22307ab87bbbSCosmo Chou return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
22317ab87bbbSCosmo Chou break;
22327ab87bbbSCosmo Chou case CrdState::packing:
22337ab87bbbSCosmo Chou if (currState != CrdState::waitData)
22347ab87bbbSCosmo Chou return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
22357ab87bbbSCosmo Chou break;
22367ab87bbbSCosmo Chou case CrdState::free:
22377ab87bbbSCosmo Chou break;
22387ab87bbbSCosmo Chou default:
22397ab87bbbSCosmo Chou return IPMI_CC_UNSPECIFIED_ERROR;
22407ab87bbbSCosmo Chou }
22417ab87bbbSCosmo Chou currState = newState;
22427ab87bbbSCosmo Chou
22437ab87bbbSCosmo Chou return IPMI_CC_OK;
22447ab87bbbSCosmo Chou }
22457ab87bbbSCosmo Chou
handleMcaBank(const CrashDumpHdr & hdr,std::span<const uint8_t> data,CrdState & currState,std::stringstream & ss)22467ab87bbbSCosmo Chou static ipmi_ret_t handleMcaBank(const CrashDumpHdr& hdr,
22477ab87bbbSCosmo Chou std::span<const uint8_t> data,
22487ab87bbbSCosmo Chou CrdState& currState, std::stringstream& ss)
22497ab87bbbSCosmo Chou {
22507ab87bbbSCosmo Chou if (data.size() < sizeof(CrdMcaBank))
22517ab87bbbSCosmo Chou return IPMI_CC_REQ_DATA_LEN_INVALID;
22527ab87bbbSCosmo Chou
22537ab87bbbSCosmo Chou ipmi_ret_t res = setDumpState(currState, CrdState::waitData);
22547ab87bbbSCosmo Chou if (res)
22557ab87bbbSCosmo Chou return res;
22567ab87bbbSCosmo Chou
22577ab87bbbSCosmo Chou const auto* pBank = reinterpret_cast<const CrdMcaBank*>(data.data());
22587ab87bbbSCosmo Chou ss << std::format(" Bank ID : 0x{:02X}, Core ID : 0x{:02X}\n",
22597ab87bbbSCosmo Chou hdr.bankHdr.bankId, hdr.bankHdr.coreId);
22607ab87bbbSCosmo Chou ss << std::format(" MCA_CTRL : 0x{:016X}\n", pBank->mcaCtrl);
22617ab87bbbSCosmo Chou ss << std::format(" MCA_STATUS : 0x{:016X}\n", pBank->mcaSts);
22627ab87bbbSCosmo Chou ss << std::format(" MCA_ADDR : 0x{:016X}\n", pBank->mcaAddr);
22637ab87bbbSCosmo Chou ss << std::format(" MCA_MISC0 : 0x{:016X}\n", pBank->mcaMisc0);
22647ab87bbbSCosmo Chou ss << std::format(" MCA_CTRL_MASK : 0x{:016X}\n", pBank->mcaCtrlMask);
22657ab87bbbSCosmo Chou ss << std::format(" MCA_CONFIG : 0x{:016X}\n", pBank->mcaConfig);
22667ab87bbbSCosmo Chou ss << std::format(" MCA_IPID : 0x{:016X}\n", pBank->mcaIpid);
22677ab87bbbSCosmo Chou ss << std::format(" MCA_SYND : 0x{:016X}\n", pBank->mcaSynd);
22687ab87bbbSCosmo Chou ss << std::format(" MCA_DESTAT : 0x{:016X}\n", pBank->mcaDestat);
22697ab87bbbSCosmo Chou ss << std::format(" MCA_DEADDR : 0x{:016X}\n", pBank->mcaDeaddr);
22707ab87bbbSCosmo Chou ss << std::format(" MCA_MISC1 : 0x{:016X}\n", pBank->mcaMisc1);
22717ab87bbbSCosmo Chou ss << "\n";
22727ab87bbbSCosmo Chou
22737ab87bbbSCosmo Chou return IPMI_CC_OK;
22747ab87bbbSCosmo Chou }
22757ab87bbbSCosmo Chou
22767ab87bbbSCosmo Chou template <typename T>
handleVirtualBank(std::span<const uint8_t> data,CrdState & currState,std::stringstream & ss)22777ab87bbbSCosmo Chou static ipmi_ret_t handleVirtualBank(std::span<const uint8_t> data,
22787ab87bbbSCosmo Chou CrdState& currState, std::stringstream& ss)
22797ab87bbbSCosmo Chou {
22807ab87bbbSCosmo Chou if (data.size() < sizeof(T))
22817ab87bbbSCosmo Chou return IPMI_CC_REQ_DATA_LEN_INVALID;
22827ab87bbbSCosmo Chou
22837ab87bbbSCosmo Chou const auto* pBank = reinterpret_cast<const T*>(data.data());
22847ab87bbbSCosmo Chou
22857ab87bbbSCosmo Chou if (data.size() < sizeof(T) + sizeof(BankCorePair) * pBank->mcaCount)
22867ab87bbbSCosmo Chou return IPMI_CC_REQ_DATA_LEN_INVALID;
22877ab87bbbSCosmo Chou
22887ab87bbbSCosmo Chou ipmi_ret_t res = setDumpState(currState, CrdState::waitData);
22897ab87bbbSCosmo Chou if (res)
22907ab87bbbSCosmo Chou return res;
22917ab87bbbSCosmo Chou
22927ab87bbbSCosmo Chou ss << " Virtual Bank\n";
22937ab87bbbSCosmo Chou ss << std::format(" S5_RESET_STATUS : 0x{:08X}\n", pBank->s5ResetSts);
22947ab87bbbSCosmo Chou ss << std::format(" PM_BREAKEVENT : 0x{:08X}\n", pBank->breakevent);
22957ab87bbbSCosmo Chou if constexpr (std::is_same_v<T, CrdVirtualBankV3>)
22967ab87bbbSCosmo Chou {
22977ab87bbbSCosmo Chou ss << std::format(" WARMCOLDRSTSTATUS : 0x{:08X}\n", pBank->rstSts);
22987ab87bbbSCosmo Chou }
22997ab87bbbSCosmo Chou ss << std::format(" PROCESSOR NUMBER : 0x{:04X}\n", pBank->procNum);
23007ab87bbbSCosmo Chou ss << std::format(" APIC ID : 0x{:08X}\n", pBank->apicId);
23017ab87bbbSCosmo Chou ss << std::format(" EAX : 0x{:08X}\n", pBank->eax);
23027ab87bbbSCosmo Chou ss << std::format(" EBX : 0x{:08X}\n", pBank->ebx);
23037ab87bbbSCosmo Chou ss << std::format(" ECX : 0x{:08X}\n", pBank->ecx);
23047ab87bbbSCosmo Chou ss << std::format(" EDX : 0x{:08X}\n", pBank->edx);
23057ab87bbbSCosmo Chou ss << " VALID LIST : ";
23067ab87bbbSCosmo Chou for (size_t i = 0; i < pBank->mcaCount; i++)
23077ab87bbbSCosmo Chou {
23087ab87bbbSCosmo Chou ss << std::format("(0x{:02X},0x{:02X}) ", pBank->mcaList[i].bankId,
23097ab87bbbSCosmo Chou pBank->mcaList[i].coreId);
23107ab87bbbSCosmo Chou }
23117ab87bbbSCosmo Chou ss << "\n\n";
23127ab87bbbSCosmo Chou
23137ab87bbbSCosmo Chou return IPMI_CC_OK;
23147ab87bbbSCosmo Chou }
23157ab87bbbSCosmo Chou
handleCpuWdtBank(std::span<const uint8_t> data,CrdState & currState,std::stringstream & ss)23167ab87bbbSCosmo Chou static ipmi_ret_t handleCpuWdtBank(std::span<const uint8_t> data,
23177ab87bbbSCosmo Chou CrdState& currState, std::stringstream& ss)
23187ab87bbbSCosmo Chou {
23197ab87bbbSCosmo Chou if (data.size() < sizeof(CrdCpuWdtBank))
23207ab87bbbSCosmo Chou return IPMI_CC_REQ_DATA_LEN_INVALID;
23217ab87bbbSCosmo Chou
23227ab87bbbSCosmo Chou ipmi_ret_t res = setDumpState(currState, CrdState::waitData);
23237ab87bbbSCosmo Chou if (res)
23247ab87bbbSCosmo Chou return res;
23257ab87bbbSCosmo Chou
23267ab87bbbSCosmo Chou const auto* pBank = reinterpret_cast<const CrdCpuWdtBank*>(data.data());
23277ab87bbbSCosmo Chou for (size_t i = 0; i < ccmNum; i++)
23287ab87bbbSCosmo Chou {
23297ab87bbbSCosmo Chou ss << std::format(" [CCM{}]\n", i);
23307ab87bbbSCosmo Chou ss << std::format(" HwAssertStsHi : 0x{:08X}\n",
23317ab87bbbSCosmo Chou pBank->hwAssertStsHi[i]);
23327ab87bbbSCosmo Chou ss << std::format(" HwAssertStsLo : 0x{:08X}\n",
23337ab87bbbSCosmo Chou pBank->hwAssertStsLo[i]);
23347ab87bbbSCosmo Chou ss << std::format(" OrigWdtAddrLogHi : 0x{:08X}\n",
23357ab87bbbSCosmo Chou pBank->origWdtAddrLogHi[i]);
23367ab87bbbSCosmo Chou ss << std::format(" OrigWdtAddrLogLo : 0x{:08X}\n",
23377ab87bbbSCosmo Chou pBank->origWdtAddrLogLo[i]);
23387ab87bbbSCosmo Chou ss << std::format(" HwAssertMskHi : 0x{:08X}\n",
23397ab87bbbSCosmo Chou pBank->hwAssertMskHi[i]);
23407ab87bbbSCosmo Chou ss << std::format(" HwAssertMskLo : 0x{:08X}\n",
23417ab87bbbSCosmo Chou pBank->hwAssertMskLo[i]);
23427ab87bbbSCosmo Chou ss << std::format(" OrigWdtAddrLogStat : 0x{:08X}\n",
23437ab87bbbSCosmo Chou pBank->origWdtAddrLogStat[i]);
23447ab87bbbSCosmo Chou }
23457ab87bbbSCosmo Chou ss << "\n";
23467ab87bbbSCosmo Chou
23477ab87bbbSCosmo Chou return IPMI_CC_OK;
23487ab87bbbSCosmo Chou }
23497ab87bbbSCosmo Chou
23507ab87bbbSCosmo Chou template <size_t N>
2351010dee04SPatrick Williams static ipmi_ret_t
handleHwAssertBank(const char * name,std::span<const uint8_t> data,CrdState & currState,std::stringstream & ss)2352010dee04SPatrick Williams handleHwAssertBank(const char* name, std::span<const uint8_t> data,
23537ab87bbbSCosmo Chou CrdState& currState, std::stringstream& ss)
23547ab87bbbSCosmo Chou {
23557ab87bbbSCosmo Chou if (data.size() < sizeof(CrdHwAssertBank<N>))
23567ab87bbbSCosmo Chou return IPMI_CC_REQ_DATA_LEN_INVALID;
23577ab87bbbSCosmo Chou
23587ab87bbbSCosmo Chou ipmi_ret_t res = setDumpState(currState, CrdState::waitData);
23597ab87bbbSCosmo Chou if (res)
23607ab87bbbSCosmo Chou return res;
23617ab87bbbSCosmo Chou
23627ab87bbbSCosmo Chou const CrdHwAssertBank<N>* pBank =
23637ab87bbbSCosmo Chou reinterpret_cast<const CrdHwAssertBank<N>*>(data.data());
23647ab87bbbSCosmo Chou
23657ab87bbbSCosmo Chou for (size_t i = 0; i < N; i++)
23667ab87bbbSCosmo Chou {
23677ab87bbbSCosmo Chou ss << std::format(" [{}{}]\n", name, i);
23687ab87bbbSCosmo Chou ss << std::format(" HwAssertStsHi : 0x{:08X}\n",
23697ab87bbbSCosmo Chou pBank->hwAssertStsHi[i]);
23707ab87bbbSCosmo Chou ss << std::format(" HwAssertStsLo : 0x{:08X}\n",
23717ab87bbbSCosmo Chou pBank->hwAssertStsLo[i]);
23727ab87bbbSCosmo Chou ss << std::format(" HwAssertMskHi : 0x{:08X}\n",
23737ab87bbbSCosmo Chou pBank->hwAssertMskHi[i]);
23747ab87bbbSCosmo Chou ss << std::format(" HwAssertMskLo : 0x{:08X}\n",
23757ab87bbbSCosmo Chou pBank->hwAssertMskLo[i]);
23767ab87bbbSCosmo Chou }
23777ab87bbbSCosmo Chou ss << "\n";
23787ab87bbbSCosmo Chou
23797ab87bbbSCosmo Chou return IPMI_CC_OK;
23807ab87bbbSCosmo Chou }
23817ab87bbbSCosmo Chou
handlePcieAerBank(std::span<const uint8_t> data,CrdState & currState,std::stringstream & ss)23827ab87bbbSCosmo Chou static ipmi_ret_t handlePcieAerBank(std::span<const uint8_t> data,
23837ab87bbbSCosmo Chou CrdState& currState, std::stringstream& ss)
23847ab87bbbSCosmo Chou {
23857ab87bbbSCosmo Chou if (data.size() < sizeof(CrdPcieAerBank))
23867ab87bbbSCosmo Chou return IPMI_CC_REQ_DATA_LEN_INVALID;
23877ab87bbbSCosmo Chou
23887ab87bbbSCosmo Chou ipmi_ret_t res = setDumpState(currState, CrdState::waitData);
23897ab87bbbSCosmo Chou if (res)
23907ab87bbbSCosmo Chou return res;
23917ab87bbbSCosmo Chou
23927ab87bbbSCosmo Chou const auto* pBank = reinterpret_cast<const CrdPcieAerBank*>(data.data());
23937ab87bbbSCosmo Chou ss << std::format(" [Bus{} Dev{} Fun{}]\n", pBank->bus, pBank->dev,
23947ab87bbbSCosmo Chou pBank->fun);
23957ab87bbbSCosmo Chou ss << std::format(" Command : 0x{:04X}\n",
23967ab87bbbSCosmo Chou pBank->cmd);
23977ab87bbbSCosmo Chou ss << std::format(" Status : 0x{:04X}\n",
23987ab87bbbSCosmo Chou pBank->sts);
23997ab87bbbSCosmo Chou ss << std::format(" Slot : 0x{:04X}\n",
24007ab87bbbSCosmo Chou pBank->slot);
24017ab87bbbSCosmo Chou ss << std::format(" Secondary Bus : 0x{:02X}\n",
24027ab87bbbSCosmo Chou pBank->secondBus);
24037ab87bbbSCosmo Chou ss << std::format(" Vendor ID : 0x{:04X}\n",
24047ab87bbbSCosmo Chou pBank->vendorId);
24057ab87bbbSCosmo Chou ss << std::format(" Device ID : 0x{:04X}\n",
24067ab87bbbSCosmo Chou pBank->devId);
24077ab87bbbSCosmo Chou ss << std::format(" Class Code : 0x{:02X}{:04X}\n",
24087ab87bbbSCosmo Chou pBank->classCodeHi, pBank->classCodeLo);
24097ab87bbbSCosmo Chou ss << std::format(" Bridge: Secondary Status : 0x{:04X}\n",
24107ab87bbbSCosmo Chou pBank->secondSts);
24117ab87bbbSCosmo Chou ss << std::format(" Bridge: Control : 0x{:04X}\n",
24127ab87bbbSCosmo Chou pBank->ctrl);
24137ab87bbbSCosmo Chou ss << std::format(" Uncorrectable Error Status : 0x{:08X}\n",
24147ab87bbbSCosmo Chou pBank->uncorrErrSts);
24157ab87bbbSCosmo Chou ss << std::format(" Uncorrectable Error Mask : 0x{:08X}\n",
24167ab87bbbSCosmo Chou pBank->uncorrErrMsk);
24177ab87bbbSCosmo Chou ss << std::format(" Uncorrectable Error Severity : 0x{:08X}\n",
24187ab87bbbSCosmo Chou pBank->uncorrErrSeverity);
24197ab87bbbSCosmo Chou ss << std::format(" Correctable Error Status : 0x{:08X}\n",
24207ab87bbbSCosmo Chou pBank->corrErrSts);
24217ab87bbbSCosmo Chou ss << std::format(" Correctable Error Mask : 0x{:08X}\n",
24227ab87bbbSCosmo Chou pBank->corrErrMsk);
24237ab87bbbSCosmo Chou ss << std::format(" Header Log DW0 : 0x{:08X}\n",
24247ab87bbbSCosmo Chou pBank->hdrLogDw0);
24257ab87bbbSCosmo Chou ss << std::format(" Header Log DW1 : 0x{:08X}\n",
24267ab87bbbSCosmo Chou pBank->hdrLogDw1);
24277ab87bbbSCosmo Chou ss << std::format(" Header Log DW2 : 0x{:08X}\n",
24287ab87bbbSCosmo Chou pBank->hdrLogDw2);
24297ab87bbbSCosmo Chou ss << std::format(" Header Log DW3 : 0x{:08X}\n",
24307ab87bbbSCosmo Chou pBank->hdrLogDw3);
24317ab87bbbSCosmo Chou ss << std::format(" Root Error Status : 0x{:08X}\n",
24327ab87bbbSCosmo Chou pBank->rootErrSts);
24337ab87bbbSCosmo Chou ss << std::format(" Correctable Error Source ID : 0x{:04X}\n",
24347ab87bbbSCosmo Chou pBank->corrErrSrcId);
24357ab87bbbSCosmo Chou ss << std::format(" Error Source ID : 0x{:04X}\n",
24367ab87bbbSCosmo Chou pBank->errSrcId);
24377ab87bbbSCosmo Chou ss << std::format(" Lane Error Status : 0x{:08X}\n",
24387ab87bbbSCosmo Chou pBank->laneErrSts);
24397ab87bbbSCosmo Chou ss << "\n";
24407ab87bbbSCosmo Chou
24417ab87bbbSCosmo Chou return IPMI_CC_OK;
24427ab87bbbSCosmo Chou }
24437ab87bbbSCosmo Chou
handleWdtRegBank(std::span<const uint8_t> data,CrdState & currState,std::stringstream & ss)24447ab87bbbSCosmo Chou static ipmi_ret_t handleWdtRegBank(std::span<const uint8_t> data,
24457ab87bbbSCosmo Chou CrdState& currState, std::stringstream& ss)
24467ab87bbbSCosmo Chou {
24477ab87bbbSCosmo Chou if (data.size() < sizeof(CrdWdtRegBank))
24487ab87bbbSCosmo Chou return IPMI_CC_REQ_DATA_LEN_INVALID;
24497ab87bbbSCosmo Chou
24507ab87bbbSCosmo Chou const auto* pBank = reinterpret_cast<const CrdWdtRegBank*>(data.data());
24517ab87bbbSCosmo Chou if (data.size() < sizeof(CrdWdtRegBank) + sizeof(uint32_t) * pBank->count)
24527ab87bbbSCosmo Chou return IPMI_CC_REQ_DATA_LEN_INVALID;
24537ab87bbbSCosmo Chou
24547ab87bbbSCosmo Chou ipmi_ret_t res = setDumpState(currState, CrdState::waitData);
24557ab87bbbSCosmo Chou if (res)
24567ab87bbbSCosmo Chou return res;
24577ab87bbbSCosmo Chou
24587ab87bbbSCosmo Chou ss << std::format(" [NBIO{}] {}\n", pBank->nbio, pBank->name);
24597ab87bbbSCosmo Chou ss << std::format(" Address: 0x{:08X}\n", pBank->addr);
24607ab87bbbSCosmo Chou ss << std::format(" Data Count: {}\n", pBank->count);
24617ab87bbbSCosmo Chou ss << " Data:\n";
24627ab87bbbSCosmo Chou for (size_t i = 0; i < pBank->count; i++)
24637ab87bbbSCosmo Chou {
24647ab87bbbSCosmo Chou ss << std::format(" {}: 0x{:08X}\n", i, pBank->data[i]);
24657ab87bbbSCosmo Chou }
24667ab87bbbSCosmo Chou ss << "\n";
24677ab87bbbSCosmo Chou
24687ab87bbbSCosmo Chou return IPMI_CC_OK;
24697ab87bbbSCosmo Chou }
24707ab87bbbSCosmo Chou
handleCrdHdrBank(std::span<const uint8_t> data,CrdState & currState,std::stringstream & ss)24717ab87bbbSCosmo Chou static ipmi_ret_t handleCrdHdrBank(std::span<const uint8_t> data,
24727ab87bbbSCosmo Chou CrdState& currState, std::stringstream& ss)
24737ab87bbbSCosmo Chou {
24747ab87bbbSCosmo Chou if (data.size() < sizeof(CrdHdrBank))
24757ab87bbbSCosmo Chou return IPMI_CC_REQ_DATA_LEN_INVALID;
24767ab87bbbSCosmo Chou
24777ab87bbbSCosmo Chou ipmi_ret_t res = setDumpState(currState, CrdState::waitData);
24787ab87bbbSCosmo Chou if (res)
24797ab87bbbSCosmo Chou return res;
24807ab87bbbSCosmo Chou
24817ab87bbbSCosmo Chou const auto* pBank = reinterpret_cast<const CrdHdrBank*>(data.data());
24827ab87bbbSCosmo Chou ss << " Crashdump Header\n";
24837ab87bbbSCosmo Chou ss << std::format(" CPU PPIN : 0x{:016X}\n", pBank->ppin);
24847ab87bbbSCosmo Chou ss << std::format(" UCODE VERSION : 0x{:08X}\n", pBank->ucodeVer);
24857ab87bbbSCosmo Chou ss << std::format(" PMIO 80h : 0x{:08X}\n", pBank->pmio);
24867ab87bbbSCosmo Chou ss << std::format(
24877ab87bbbSCosmo Chou " BIT0 - SMN Parity/SMN Timeouts PSP/SMU Parity and ECC/SMN On-Package Link Error : {}\n",
24887ab87bbbSCosmo Chou pBank->pmio & 0x1);
24897ab87bbbSCosmo Chou ss << std::format(" BIT2 - PSP Parity and ECC : {}\n",
24907ab87bbbSCosmo Chou (pBank->pmio & 0x4) >> 2);
24917ab87bbbSCosmo Chou ss << std::format(" BIT3 - SMN Timeouts SMU : {}\n",
24927ab87bbbSCosmo Chou (pBank->pmio & 0x8) >> 3);
24937ab87bbbSCosmo Chou ss << std::format(" BIT4 - SMN Off-Package Link Packet Error : {}\n",
24947ab87bbbSCosmo Chou (pBank->pmio & 0x10) >> 4);
24957ab87bbbSCosmo Chou ss << "\n";
24967ab87bbbSCosmo Chou
24977ab87bbbSCosmo Chou return IPMI_CC_OK;
24987ab87bbbSCosmo Chou }
24997ab87bbbSCosmo Chou
getFilename(const std::filesystem::path & dir,const std::string & prefix)25007ab87bbbSCosmo Chou static std::string getFilename(const std::filesystem::path& dir,
25017ab87bbbSCosmo Chou const std::string& prefix)
25027ab87bbbSCosmo Chou {
25037ab87bbbSCosmo Chou std::vector<int> indices;
25047ab87bbbSCosmo Chou std::regex pattern(prefix + "(\\d+)\\.txt");
25057ab87bbbSCosmo Chou
25067ab87bbbSCosmo Chou for (const auto& entry : std::filesystem::directory_iterator(dir))
25077ab87bbbSCosmo Chou {
25087ab87bbbSCosmo Chou std::string filename = entry.path().filename().string();
25097ab87bbbSCosmo Chou std::smatch match;
25107ab87bbbSCosmo Chou if (std::regex_match(filename, match, pattern))
25117ab87bbbSCosmo Chou indices.push_back(std::stoi(match[1]));
25127ab87bbbSCosmo Chou }
25137ab87bbbSCosmo Chou
25147ab87bbbSCosmo Chou std::sort(indices.rbegin(), indices.rend());
25157ab87bbbSCosmo Chou while (indices.size() > 2) // keep 3 files, so remove if more than 2
25167ab87bbbSCosmo Chou {
25177ab87bbbSCosmo Chou std::filesystem::remove(
25187ab87bbbSCosmo Chou dir / (prefix + std::to_string(indices.back()) + ".txt"));
25197ab87bbbSCosmo Chou indices.pop_back();
25207ab87bbbSCosmo Chou }
25217ab87bbbSCosmo Chou
25227ab87bbbSCosmo Chou int nextIndex = indices.empty() ? 1 : indices.front() + 1;
25237ab87bbbSCosmo Chou return prefix + std::to_string(nextIndex) + ".txt";
25247ab87bbbSCosmo Chou }
25257ab87bbbSCosmo Chou
handleCtrlBank(std::span<const uint8_t> data,CrdState & currState,std::stringstream & ss)25267ab87bbbSCosmo Chou static ipmi_ret_t handleCtrlBank(std::span<const uint8_t> data,
25277ab87bbbSCosmo Chou CrdState& currState, std::stringstream& ss)
25287ab87bbbSCosmo Chou {
25297ab87bbbSCosmo Chou if (data.empty())
25307ab87bbbSCosmo Chou return IPMI_CC_REQ_DATA_LEN_INVALID;
25317ab87bbbSCosmo Chou
25327ab87bbbSCosmo Chou switch (static_cast<CrdCtrl>(data[0]))
25337ab87bbbSCosmo Chou {
25347ab87bbbSCosmo Chou case CrdCtrl::getState:
25357ab87bbbSCosmo Chou break;
25367ab87bbbSCosmo Chou case CrdCtrl::finish:
25377ab87bbbSCosmo Chou {
25387ab87bbbSCosmo Chou ipmi_ret_t res = setDumpState(currState, CrdState::packing);
25397ab87bbbSCosmo Chou if (res)
25407ab87bbbSCosmo Chou return res;
25417ab87bbbSCosmo Chou
25427ab87bbbSCosmo Chou const std::filesystem::path dumpDir = "/var/lib/fb-ipmi-oem";
25437ab87bbbSCosmo Chou std::string filename = getFilename(dumpDir, "crashdump_");
25447ab87bbbSCosmo Chou std::ofstream outFile(dumpDir / filename);
25457ab87bbbSCosmo Chou if (!outFile.is_open())
25467ab87bbbSCosmo Chou return IPMI_CC_UNSPECIFIED_ERROR;
25477ab87bbbSCosmo Chou
25487ab87bbbSCosmo Chou auto now = std::chrono::system_clock::to_time_t(
25497ab87bbbSCosmo Chou std::chrono::system_clock::now());
25507ab87bbbSCosmo Chou outFile << "Crash Dump generated at: "
25517ab87bbbSCosmo Chou << std::put_time(std::localtime(&now), "%Y-%m-%d %H:%M:%S")
25527ab87bbbSCosmo Chou << "\n\n";
25537ab87bbbSCosmo Chou outFile << ss.str();
25547ab87bbbSCosmo Chou outFile.close();
25557ab87bbbSCosmo Chou ss.str("");
25567ab87bbbSCosmo Chou ss.clear();
25577ab87bbbSCosmo Chou setDumpState(currState, CrdState::free);
25587ab87bbbSCosmo Chou break;
25597ab87bbbSCosmo Chou }
25607ab87bbbSCosmo Chou default:
25617ab87bbbSCosmo Chou return ccInvalidParam;
25627ab87bbbSCosmo Chou }
25637ab87bbbSCosmo Chou
25647ab87bbbSCosmo Chou return IPMI_CC_OK;
25657ab87bbbSCosmo Chou }
25667ab87bbbSCosmo Chou
ipmiOemCrashdump(ipmi::Context::ptr ctx,std::vector<uint8_t> reqData)2567010dee04SPatrick Williams ipmi::RspType<std::vector<uint8_t>> ipmiOemCrashdump(
2568010dee04SPatrick Williams [[maybe_unused]] ipmi::Context::ptr ctx, std::vector<uint8_t> reqData)
25697ab87bbbSCosmo Chou {
25707ab87bbbSCosmo Chou static CrdState dumpState = CrdState::free;
25717ab87bbbSCosmo Chou static std::stringstream ss;
25727ab87bbbSCosmo Chou
25737ab87bbbSCosmo Chou if (reqData.size() < sizeof(CrashDumpHdr))
25747ab87bbbSCosmo Chou return ipmi::responseReqDataLenInvalid();
25757ab87bbbSCosmo Chou
25767ab87bbbSCosmo Chou const auto* pHdr = reinterpret_cast<const CrashDumpHdr*>(reqData.data());
25777ab87bbbSCosmo Chou std::span<const uint8_t> bData{reqData.data() + sizeof(CrashDumpHdr),
25787ab87bbbSCosmo Chou reqData.size() - sizeof(CrashDumpHdr)};
25797ab87bbbSCosmo Chou ipmi_ret_t res;
25807ab87bbbSCosmo Chou
25817ab87bbbSCosmo Chou switch (pHdr->bankHdr.bankType)
25827ab87bbbSCosmo Chou {
25837ab87bbbSCosmo Chou case BankType::mca:
25847ab87bbbSCosmo Chou res = handleMcaBank(*pHdr, bData, dumpState, ss);
25857ab87bbbSCosmo Chou break;
25867ab87bbbSCosmo Chou case BankType::virt:
25877ab87bbbSCosmo Chou if (pHdr->bankHdr.version >= 3)
25887ab87bbbSCosmo Chou {
25897ab87bbbSCosmo Chou res = handleVirtualBank<CrdVirtualBankV3>(bData, dumpState, ss);
25907ab87bbbSCosmo Chou break;
25917ab87bbbSCosmo Chou }
25927ab87bbbSCosmo Chou res = handleVirtualBank<CrdVirtualBankV2>(bData, dumpState, ss);
25937ab87bbbSCosmo Chou break;
25947ab87bbbSCosmo Chou case BankType::cpuWdt:
25957ab87bbbSCosmo Chou res = handleCpuWdtBank(bData, dumpState, ss);
25967ab87bbbSCosmo Chou break;
25977ab87bbbSCosmo Chou case BankType::tcdx:
25987ab87bbbSCosmo Chou res = handleHwAssertBank<tcdxNum>("TCDX", bData, dumpState, ss);
25997ab87bbbSCosmo Chou break;
26007ab87bbbSCosmo Chou case BankType::cake:
26017ab87bbbSCosmo Chou res = handleHwAssertBank<cakeNum>("CAKE", bData, dumpState, ss);
26027ab87bbbSCosmo Chou break;
26037ab87bbbSCosmo Chou case BankType::pie0:
26047ab87bbbSCosmo Chou res = handleHwAssertBank<pie0Num>("PIE", bData, dumpState, ss);
26057ab87bbbSCosmo Chou break;
26067ab87bbbSCosmo Chou case BankType::iom:
26077ab87bbbSCosmo Chou res = handleHwAssertBank<iomNum>("IOM", bData, dumpState, ss);
26087ab87bbbSCosmo Chou break;
26097ab87bbbSCosmo Chou case BankType::ccix:
26107ab87bbbSCosmo Chou res = handleHwAssertBank<ccixNum>("CCIX", bData, dumpState, ss);
26117ab87bbbSCosmo Chou break;
26127ab87bbbSCosmo Chou case BankType::cs:
26137ab87bbbSCosmo Chou res = handleHwAssertBank<csNum>("CS", bData, dumpState, ss);
26147ab87bbbSCosmo Chou break;
26157ab87bbbSCosmo Chou case BankType::pcieAer:
26167ab87bbbSCosmo Chou res = handlePcieAerBank(bData, dumpState, ss);
26177ab87bbbSCosmo Chou break;
26187ab87bbbSCosmo Chou case BankType::wdtReg:
26197ab87bbbSCosmo Chou res = handleWdtRegBank(bData, dumpState, ss);
26207ab87bbbSCosmo Chou break;
26217ab87bbbSCosmo Chou case BankType::ctrl:
26227ab87bbbSCosmo Chou res = handleCtrlBank(bData, dumpState, ss);
26237ab87bbbSCosmo Chou if (res == IPMI_CC_OK &&
26247ab87bbbSCosmo Chou static_cast<CrdCtrl>(bData[0]) == CrdCtrl::getState)
26257ab87bbbSCosmo Chou {
26267ab87bbbSCosmo Chou return ipmi::responseSuccess(
26277ab87bbbSCosmo Chou std::vector<uint8_t>{static_cast<uint8_t>(dumpState)});
26287ab87bbbSCosmo Chou }
26297ab87bbbSCosmo Chou break;
26307ab87bbbSCosmo Chou case BankType::crdHdr:
26317ab87bbbSCosmo Chou res = handleCrdHdrBank(bData, dumpState, ss);
26327ab87bbbSCosmo Chou break;
26337ab87bbbSCosmo Chou default:
26347ab87bbbSCosmo Chou return ipmi::responseInvalidFieldRequest();
26357ab87bbbSCosmo Chou }
26367ab87bbbSCosmo Chou
26377ab87bbbSCosmo Chou return ipmi::response(res);
26387ab87bbbSCosmo Chou }
26397ab87bbbSCosmo Chou
registerOEMFunctions(void)2640e7d23d0eSVijay Khemka static void registerOEMFunctions(void)
2641e7d23d0eSVijay Khemka {
26421d4a0697SVijay Khemka /* Get OEM data from json file */
26431d4a0697SVijay Khemka std::ifstream file(JSON_OEM_DATA_FILE);
26441d4a0697SVijay Khemka if (file)
2645feaa9811SVijay Khemka {
2646*ac597172SPeter Yin try
2647*ac597172SPeter Yin {
26481d4a0697SVijay Khemka file >> oemData;
2649*ac597172SPeter Yin }
2650*ac597172SPeter Yin // If parsing fails, initialize oemData as an empty JSON and
2651*ac597172SPeter Yin // overwrite the file
2652*ac597172SPeter Yin catch (const nlohmann::json::parse_error& e)
2653*ac597172SPeter Yin {
2654*ac597172SPeter Yin lg2::error("Error parsing JSON file: {ERROR}", "ERROR", e);
2655*ac597172SPeter Yin oemData = nlohmann::json::object();
2656*ac597172SPeter Yin std::ofstream outFile(JSON_OEM_DATA_FILE, std::ofstream::trunc);
2657*ac597172SPeter Yin outFile << oemData.dump(4); // Write empty JSON object to the file
2658*ac597172SPeter Yin outFile.close();
2659*ac597172SPeter Yin }
2660feaa9811SVijay Khemka file.close();
2661feaa9811SVijay Khemka }
2662*ac597172SPeter Yin else
2663*ac597172SPeter Yin {
2664*ac597172SPeter Yin lg2::info("Failed to open JSON file.");
2665*ac597172SPeter Yin }
26661d4a0697SVijay Khemka
2667*ac597172SPeter Yin lg2::info("Registering OEM commands.");
26687c0aea49SVijay Khemka
2669e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_INFO,
2670e7d23d0eSVijay Khemka NULL, ipmiOemDbgGetFrameInfo,
2671e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug frame info
2672e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ,
2673e7d23d0eSVijay Khemka CMD_OEM_USB_DBG_GET_UPDATED_FRAMES, NULL,
2674e7d23d0eSVijay Khemka ipmiOemDbgGetUpdFrames,
2675e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug updated frames
2676e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_POST_DESC,
2677e7d23d0eSVijay Khemka NULL, ipmiOemDbgGetPostDesc,
2678e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug post description
2679e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_GPIO_DESC,
2680e7d23d0eSVijay Khemka NULL, ipmiOemDbgGetGpioDesc,
2681e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug gpio description
2682e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_DATA,
2683e7d23d0eSVijay Khemka NULL, ipmiOemDbgGetFrameData,
2684e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug frame data
2685e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_CTRL_PANEL,
2686e7d23d0eSVijay Khemka NULL, ipmiOemDbgGetCtrlPanel,
2687e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug control panel
2688e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_DIMM_INFO, NULL,
2689e7d23d0eSVijay Khemka ipmiOemSetDimmInfo,
2690e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set Dimm Info
26911d4a0697SVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_BOARD_ID, NULL,
26921d4a0697SVijay Khemka ipmiOemGetBoardID,
26931d4a0697SVijay Khemka PRIVILEGE_USER); // Get Board ID
26944ae63e71SBonnie Lo ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnOemOne,
26954ae63e71SBonnie Lo CMD_OEM_GET_80PORT_RECORD, ipmi::Privilege::User,
26964ae63e71SBonnie Lo ipmiOemGet80PortRecord); // Get 80 Port Record
2697e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_MACHINE_CONFIG_INFO, NULL,
2698e7d23d0eSVijay Khemka ipmiOemSetMachineCfgInfo,
2699e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set Machine Config Info
2700e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_START, NULL,
2701e7d23d0eSVijay Khemka ipmiOemSetPostStart,
2702e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set POST start
2703e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_END, NULL,
2704e7d23d0eSVijay Khemka ipmiOemSetPostEnd,
2705e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set POST End
27061d4a0697SVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPIN_INFO, NULL,
27071d4a0697SVijay Khemka ipmiOemSetPPINInfo,
27081d4a0697SVijay Khemka PRIVILEGE_USER); // Set PPIN Info
27095f8e3435SManikandan Elumalai #if BIC_ENABLED
27105f8e3435SManikandan Elumalai
27115f8e3435SManikandan Elumalai ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
27125f8e3435SManikandan Elumalai ipmi::cmdSetSystemGuid, ipmi::Privilege::User,
27135f8e3435SManikandan Elumalai ipmiOemSetSystemGuid);
27145f8e3435SManikandan Elumalai #else
27155f8e3435SManikandan Elumalai
2716f2246ce8SVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_SYSTEM_GUID, NULL,
2717f2246ce8SVijay Khemka ipmiOemSetSystemGuid,
2718f2246ce8SVijay Khemka PRIVILEGE_USER); // Set System GUID
27195f8e3435SManikandan Elumalai #endif
27201d4a0697SVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_ADR_TRIGGER, NULL,
27211d4a0697SVijay Khemka ipmiOemSetAdrTrigger,
27221d4a0697SVijay Khemka PRIVILEGE_USER); // Set ADR Trigger
2723e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_BIOS_FLASH_INFO, NULL,
2724e7d23d0eSVijay Khemka ipmiOemSetBiosFlashInfo,
2725e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set Bios Flash Info
2726e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPR, NULL, ipmiOemSetPpr,
2727e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set PPR
2728e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_PPR, NULL, ipmiOemGetPpr,
2729e7d23d0eSVijay Khemka PRIVILEGE_USER); // Get PPR
27301d4a0697SVijay Khemka /* FB OEM QC Commands */
2731d532fecaSKarthikeyan Pasupathi ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFour,
2732d532fecaSKarthikeyan Pasupathi CMD_OEM_Q_SET_PROC_INFO, ipmi::Privilege::User,
2733d532fecaSKarthikeyan Pasupathi ipmiOemQSetProcInfo); // Set Proc Info
2734d532fecaSKarthikeyan Pasupathi ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFour,
2735d532fecaSKarthikeyan Pasupathi CMD_OEM_Q_GET_PROC_INFO, ipmi::Privilege::User,
2736d532fecaSKarthikeyan Pasupathi ipmiOemQGetProcInfo); // Get Proc Info
273710ff3d86SKarthikeyan Pasupathi ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFour,
273810ff3d86SKarthikeyan Pasupathi ipmi::cmdSetQDimmInfo, ipmi::Privilege::User,
273910ff3d86SKarthikeyan Pasupathi ipmiOemQSetDimmInfo); // Set Dimm Info
274010ff3d86SKarthikeyan Pasupathi ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFour,
274110ff3d86SKarthikeyan Pasupathi ipmi::cmdGetQDimmInfo, ipmi::Privilege::User,
274210ff3d86SKarthikeyan Pasupathi ipmiOemQGetDimmInfo); // Get Dimm Info
27431d4a0697SVijay Khemka ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_DRIVE_INFO, NULL,
27441d4a0697SVijay Khemka ipmiOemQSetDriveInfo,
27451d4a0697SVijay Khemka PRIVILEGE_USER); // Set Drive Info
27461d4a0697SVijay Khemka ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_DRIVE_INFO, NULL,
27471d4a0697SVijay Khemka ipmiOemQGetDriveInfo,
27481d4a0697SVijay Khemka PRIVILEGE_USER); // Get Drive Info
2749dd14c0f7SVijay Khemka
2750dd14c0f7SVijay Khemka /* FB OEM DCMI Commands as per DCMI spec 1.5 Section 6 */
2751010dee04SPatrick Williams ipmi::registerGroupHandler(
2752010dee04SPatrick Williams ipmi::prioOpenBmcBase, groupDCMI, ipmi::dcmi::cmdGetPowerReading,
2753dd14c0f7SVijay Khemka ipmi::Privilege::User,
2754dd14c0f7SVijay Khemka ipmiOemDCMIGetPowerReading); // Get Power Reading
2755dd14c0f7SVijay Khemka
2756010dee04SPatrick Williams ipmi::registerGroupHandler(
2757010dee04SPatrick Williams ipmi::prioOpenBmcBase, groupDCMI, ipmi::dcmi::cmdGetPowerLimit,
2758dd14c0f7SVijay Khemka ipmi::Privilege::User,
2759dd14c0f7SVijay Khemka ipmiOemDCMIGetPowerLimit); // Get Power Limit
2760dd14c0f7SVijay Khemka
2761010dee04SPatrick Williams ipmi::registerGroupHandler(
2762010dee04SPatrick Williams ipmi::prioOpenBmcBase, groupDCMI, ipmi::dcmi::cmdSetPowerLimit,
2763dd14c0f7SVijay Khemka ipmi::Privilege::Operator,
2764dd14c0f7SVijay Khemka ipmiOemDCMISetPowerLimit); // Set Power Limit
2765dd14c0f7SVijay Khemka
2766010dee04SPatrick Williams ipmi::registerGroupHandler(
2767010dee04SPatrick Williams ipmi::prioOpenBmcBase, groupDCMI, ipmi::dcmi::cmdActDeactivatePwrLimit,
2768dd14c0f7SVijay Khemka ipmi::Privilege::Operator,
2769dd14c0f7SVijay Khemka ipmiOemDCMIApplyPowerLimit); // Apply Power Limit
2770dd14c0f7SVijay Khemka
2771f0cf6658SJayashree-D /* FB OEM BOOT ORDER COMMANDS */
2772f0cf6658SJayashree-D ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
2773f0cf6658SJayashree-D CMD_OEM_GET_BOOT_ORDER, ipmi::Privilege::User,
2774f0cf6658SJayashree-D ipmiOemGetBootOrder); // Get Boot Order
2775f0cf6658SJayashree-D
2776f0cf6658SJayashree-D ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
2777f0cf6658SJayashree-D CMD_OEM_SET_BOOT_ORDER, ipmi::Privilege::User,
2778f0cf6658SJayashree-D ipmiOemSetBootOrder); // Set Boot Order
2779f0cf6658SJayashree-D
27807ab87bbbSCosmo Chou ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
278199d42b6eSCosmo Chou CMD_OEM_GET_HTTPS_BOOT_DATA, ipmi::Privilege::User,
278299d42b6eSCosmo Chou ipmiOemGetHttpsData);
278399d42b6eSCosmo Chou
278499d42b6eSCosmo Chou ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
278599d42b6eSCosmo Chou CMD_OEM_GET_HTTPS_BOOT_ATTR, ipmi::Privilege::User,
278699d42b6eSCosmo Chou ipmiOemGetHttpsAttr);
278799d42b6eSCosmo Chou
278899d42b6eSCosmo Chou ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
27897ab87bbbSCosmo Chou CMD_OEM_CRASHDUMP, ipmi::Privilege::User,
27907ab87bbbSCosmo Chou ipmiOemCrashdump);
27917ab87bbbSCosmo Chou
2792e7d23d0eSVijay Khemka return;
2793e7d23d0eSVijay Khemka }
2794e7d23d0eSVijay Khemka
2795e7d23d0eSVijay Khemka } // namespace ipmi
2796