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 #include <ipmid/api.h> 20e7d23d0eSVijay Khemka 21e7d23d0eSVijay Khemka #include <array> 22e7d23d0eSVijay Khemka #include <commandutils.hpp> 23e7d23d0eSVijay Khemka #include <cstring> 24e7d23d0eSVijay Khemka #include <iostream> 25e7d23d0eSVijay Khemka #include <oemcommands.hpp> 26*1b6fae3fSVijay Khemka #include <ipmid/utils.hpp> 27e7d23d0eSVijay Khemka #include <phosphor-logging/log.hpp> 28e7d23d0eSVijay Khemka #include <sdbusplus/bus.hpp> 29e7d23d0eSVijay Khemka #include <string> 30e7d23d0eSVijay Khemka #include <vector> 31e7d23d0eSVijay Khemka 32e7d23d0eSVijay Khemka #define SIZE_IANA_ID 3 33e7d23d0eSVijay Khemka 34e7d23d0eSVijay Khemka namespace ipmi 35e7d23d0eSVijay Khemka { 36e7d23d0eSVijay Khemka static void registerOEMFunctions() __attribute__((constructor)); 37e7d23d0eSVijay Khemka sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection()); // from ipmid/api.h 38e7d23d0eSVijay Khemka static constexpr size_t maxFRUStringLength = 0x3F; 39e7d23d0eSVijay Khemka 40e7d23d0eSVijay Khemka ipmi_ret_t plat_udbg_get_post_desc(uint8_t, uint8_t *, uint8_t, uint8_t *, 41e7d23d0eSVijay Khemka uint8_t *, uint8_t *); 42e7d23d0eSVijay Khemka ipmi_ret_t plat_udbg_get_frame_data(uint8_t, uint8_t, uint8_t *, uint8_t *, 43e7d23d0eSVijay Khemka uint8_t *); 44e7d23d0eSVijay Khemka ipmi_ret_t plat_udbg_control_panel(uint8_t, uint8_t, uint8_t, uint8_t *, 45e7d23d0eSVijay Khemka uint8_t *); 46*1b6fae3fSVijay Khemka namespace variant_ns = sdbusplus::message::variant_ns; 47*1b6fae3fSVijay Khemka 48*1b6fae3fSVijay Khemka enum class LanParam : uint8_t 49*1b6fae3fSVijay Khemka { 50*1b6fae3fSVijay Khemka INPROGRESS = 0, 51*1b6fae3fSVijay Khemka AUTHSUPPORT = 1, 52*1b6fae3fSVijay Khemka AUTHENABLES = 2, 53*1b6fae3fSVijay Khemka IP = 3, 54*1b6fae3fSVijay Khemka IPSRC = 4, 55*1b6fae3fSVijay Khemka MAC = 5, 56*1b6fae3fSVijay Khemka SUBNET = 6, 57*1b6fae3fSVijay Khemka GATEWAY = 12, 58*1b6fae3fSVijay Khemka VLAN = 20, 59*1b6fae3fSVijay Khemka CIPHER_SUITE_COUNT = 22, 60*1b6fae3fSVijay Khemka CIPHER_SUITE_ENTRIES = 23, 61*1b6fae3fSVijay Khemka IPV6 = 59, 62*1b6fae3fSVijay Khemka }; 63*1b6fae3fSVijay Khemka 64*1b6fae3fSVijay Khemka ipmi_ret_t getNetworkData(uint8_t lan_param, char *data) 65*1b6fae3fSVijay Khemka { 66*1b6fae3fSVijay Khemka ipmi_ret_t rc = IPMI_CC_OK; 67*1b6fae3fSVijay Khemka sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection()); 68*1b6fae3fSVijay Khemka 69*1b6fae3fSVijay Khemka const std::string ethdevice = "eth0"; 70*1b6fae3fSVijay Khemka 71*1b6fae3fSVijay Khemka switch (static_cast<LanParam>(lan_param)) 72*1b6fae3fSVijay Khemka { 73*1b6fae3fSVijay Khemka case LanParam::IP: 74*1b6fae3fSVijay Khemka { 75*1b6fae3fSVijay Khemka auto ethIP = ethdevice + "/" + ipmi::network::IP_TYPE; 76*1b6fae3fSVijay Khemka std::string ipaddress; 77*1b6fae3fSVijay Khemka auto ipObjectInfo = ipmi::getIPObject( 78*1b6fae3fSVijay Khemka bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP); 79*1b6fae3fSVijay Khemka 80*1b6fae3fSVijay Khemka auto properties = ipmi::getAllDbusProperties( 81*1b6fae3fSVijay Khemka bus, ipObjectInfo.second, ipObjectInfo.first, 82*1b6fae3fSVijay Khemka ipmi::network::IP_INTERFACE); 83*1b6fae3fSVijay Khemka 84*1b6fae3fSVijay Khemka ipaddress = variant_ns::get<std::string>(properties["Address"]); 85*1b6fae3fSVijay Khemka 86*1b6fae3fSVijay Khemka std::strcpy(data, ipaddress.c_str()); 87*1b6fae3fSVijay Khemka } 88*1b6fae3fSVijay Khemka break; 89*1b6fae3fSVijay Khemka 90*1b6fae3fSVijay Khemka case LanParam::IPV6: 91*1b6fae3fSVijay Khemka { 92*1b6fae3fSVijay Khemka auto ethIP = ethdevice + "/ipv6"; 93*1b6fae3fSVijay Khemka std::string ipaddress; 94*1b6fae3fSVijay Khemka auto ipObjectInfo = ipmi::getIPObject( 95*1b6fae3fSVijay Khemka bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP); 96*1b6fae3fSVijay Khemka 97*1b6fae3fSVijay Khemka auto properties = ipmi::getAllDbusProperties( 98*1b6fae3fSVijay Khemka bus, ipObjectInfo.second, ipObjectInfo.first, 99*1b6fae3fSVijay Khemka ipmi::network::IP_INTERFACE); 100*1b6fae3fSVijay Khemka 101*1b6fae3fSVijay Khemka ipaddress = variant_ns::get<std::string>(properties["Address"]); 102*1b6fae3fSVijay Khemka 103*1b6fae3fSVijay Khemka std::strcpy(data, ipaddress.c_str()); 104*1b6fae3fSVijay Khemka } 105*1b6fae3fSVijay Khemka break; 106*1b6fae3fSVijay Khemka 107*1b6fae3fSVijay Khemka case LanParam::MAC: 108*1b6fae3fSVijay Khemka { 109*1b6fae3fSVijay Khemka std::string macAddress; 110*1b6fae3fSVijay Khemka auto macObjectInfo = 111*1b6fae3fSVijay Khemka ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE, 112*1b6fae3fSVijay Khemka ipmi::network::ROOT, ethdevice); 113*1b6fae3fSVijay Khemka 114*1b6fae3fSVijay Khemka auto variant = ipmi::getDbusProperty( 115*1b6fae3fSVijay Khemka bus, macObjectInfo.second, macObjectInfo.first, 116*1b6fae3fSVijay Khemka ipmi::network::MAC_INTERFACE, "MACAddress"); 117*1b6fae3fSVijay Khemka 118*1b6fae3fSVijay Khemka macAddress = variant_ns::get<std::string>(variant); 119*1b6fae3fSVijay Khemka 120*1b6fae3fSVijay Khemka sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT, 121*1b6fae3fSVijay Khemka (data), (data + 1), (data + 2), (data + 3), (data + 4), 122*1b6fae3fSVijay Khemka (data + 5)); 123*1b6fae3fSVijay Khemka std::strcpy(data, macAddress.c_str()); 124*1b6fae3fSVijay Khemka } 125*1b6fae3fSVijay Khemka break; 126*1b6fae3fSVijay Khemka 127*1b6fae3fSVijay Khemka default: 128*1b6fae3fSVijay Khemka rc = IPMI_CC_PARM_OUT_OF_RANGE; 129*1b6fae3fSVijay Khemka } 130*1b6fae3fSVijay Khemka return rc; 131*1b6fae3fSVijay Khemka } 132e7d23d0eSVijay Khemka 133e7d23d0eSVijay Khemka // return code: 0 successful 134e7d23d0eSVijay Khemka int8_t getFruData(std::string &data, std::string &name) 135e7d23d0eSVijay Khemka { 136e7d23d0eSVijay Khemka std::string objpath = "/xyz/openbmc_project/FruDevice"; 137e7d23d0eSVijay Khemka std::string intf = "xyz.openbmc_project.FruDeviceManager"; 138e7d23d0eSVijay Khemka std::string service = getService(dbus, intf, objpath); 139e7d23d0eSVijay Khemka ObjectValueTree valueTree = getManagedObjects(dbus, service, "/"); 140e7d23d0eSVijay Khemka if (valueTree.empty()) 141e7d23d0eSVijay Khemka { 142e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>( 143e7d23d0eSVijay Khemka "No object implements interface", 144e7d23d0eSVijay Khemka phosphor::logging::entry("INTF=%s", intf.c_str())); 145e7d23d0eSVijay Khemka return -1; 146e7d23d0eSVijay Khemka } 147e7d23d0eSVijay Khemka 148e7d23d0eSVijay Khemka for (const auto &item : valueTree) 149e7d23d0eSVijay Khemka { 150e7d23d0eSVijay Khemka auto interface = item.second.find("xyz.openbmc_project.FruDevice"); 151e7d23d0eSVijay Khemka if (interface == item.second.end()) 152e7d23d0eSVijay Khemka { 153e7d23d0eSVijay Khemka continue; 154e7d23d0eSVijay Khemka } 155e7d23d0eSVijay Khemka 156e7d23d0eSVijay Khemka auto property = interface->second.find(name.c_str()); 157e7d23d0eSVijay Khemka if (property == interface->second.end()) 158e7d23d0eSVijay Khemka { 159e7d23d0eSVijay Khemka continue; 160e7d23d0eSVijay Khemka } 161e7d23d0eSVijay Khemka 162e7d23d0eSVijay Khemka try 163e7d23d0eSVijay Khemka { 164e7d23d0eSVijay Khemka Value variant = property->second; 165e7d23d0eSVijay Khemka std::string &result = 166e7d23d0eSVijay Khemka sdbusplus::message::variant_ns::get<std::string>(variant); 167e7d23d0eSVijay Khemka if (result.size() > maxFRUStringLength) 168e7d23d0eSVijay Khemka { 169e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>( 170e7d23d0eSVijay Khemka "FRU serial number exceed maximum length"); 171e7d23d0eSVijay Khemka return -1; 172e7d23d0eSVijay Khemka } 173e7d23d0eSVijay Khemka data = result; 174e7d23d0eSVijay Khemka return 0; 175e7d23d0eSVijay Khemka } 176e7d23d0eSVijay Khemka catch (sdbusplus::message::variant_ns::bad_variant_access &e) 177e7d23d0eSVijay Khemka { 178e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::ERR>(e.what()); 179e7d23d0eSVijay Khemka return -1; 180e7d23d0eSVijay Khemka } 181e7d23d0eSVijay Khemka } 182e7d23d0eSVijay Khemka return -1; 183e7d23d0eSVijay Khemka } 184e7d23d0eSVijay Khemka 185e7d23d0eSVijay Khemka typedef struct 186e7d23d0eSVijay Khemka { 187e7d23d0eSVijay Khemka uint8_t cur_power_state; 188e7d23d0eSVijay Khemka uint8_t last_power_event; 189e7d23d0eSVijay Khemka uint8_t misc_power_state; 190e7d23d0eSVijay Khemka uint8_t front_panel_button_cap_status; 191e7d23d0eSVijay Khemka } ipmi_get_chassis_status_t; 192e7d23d0eSVijay Khemka 193e7d23d0eSVijay Khemka // Todo: Needs to update this as per power policy when integrated 194e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 195e7d23d0eSVijay Khemka // Get Chassis Status commands 196e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 197e7d23d0eSVijay Khemka ipmi_ret_t ipmiGetChassisStatus(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 198e7d23d0eSVijay Khemka ipmi_request_t request, 199e7d23d0eSVijay Khemka ipmi_response_t response, 200e7d23d0eSVijay Khemka ipmi_data_len_t data_len, 201e7d23d0eSVijay Khemka ipmi_context_t context) 202e7d23d0eSVijay Khemka { 203e7d23d0eSVijay Khemka ipmi_get_chassis_status_t chassis_status; 204e7d23d0eSVijay Khemka uint8_t s = 2; 205e7d23d0eSVijay Khemka 206e7d23d0eSVijay Khemka *data_len = 4; 207e7d23d0eSVijay Khemka 208e7d23d0eSVijay Khemka // Current Power State 209e7d23d0eSVijay Khemka // [7] reserved 210e7d23d0eSVijay Khemka // [6..5] power restore policy 211e7d23d0eSVijay Khemka // 00b = chassis stays powered off after AC/mains returns 212e7d23d0eSVijay Khemka // 01b = after AC returns, power is restored to the state that was 213e7d23d0eSVijay Khemka // in effect when AC/mains was lost. 214e7d23d0eSVijay Khemka // 10b = chassis always powers up after AC/mains returns 215e7d23d0eSVijay Khemka // 11b = unknow 216e7d23d0eSVijay Khemka // Set to 00b, by observing the hardware behavior. 217e7d23d0eSVijay Khemka // Do we need to define a dbus property to identify the restore 218e7d23d0eSVijay Khemka // policy? 219e7d23d0eSVijay Khemka 220e7d23d0eSVijay Khemka // [4] power control fault 221e7d23d0eSVijay Khemka // 1b = controller attempted to turn system power on or off, but 222e7d23d0eSVijay Khemka // system did not enter desired state. 223e7d23d0eSVijay Khemka // Set to 0b, since We don't support it.. 224e7d23d0eSVijay Khemka 225e7d23d0eSVijay Khemka // [3] power fault 226e7d23d0eSVijay Khemka // 1b = fault detected in main power subsystem. 227e7d23d0eSVijay Khemka // set to 0b. for we don't support it. 228e7d23d0eSVijay Khemka 229e7d23d0eSVijay Khemka // [2] 1b = interlock (chassis is presently shut down because a chassis 230e7d23d0eSVijay Khemka // panel interlock switch is active). (IPMI 1.5) 231e7d23d0eSVijay Khemka // set to 0b, for we don't support it. 232e7d23d0eSVijay Khemka 233e7d23d0eSVijay Khemka // [1] power overload 234e7d23d0eSVijay Khemka // 1b = system shutdown because of power overload condition. 235e7d23d0eSVijay Khemka // set to 0b, for we don't support it. 236e7d23d0eSVijay Khemka 237e7d23d0eSVijay Khemka // [0] power is on 238e7d23d0eSVijay Khemka // 1b = system power is on 239e7d23d0eSVijay Khemka // 0b = system power is off(soft-off S4/S5, or mechanical off) 240e7d23d0eSVijay Khemka 241e7d23d0eSVijay Khemka chassis_status.cur_power_state = ((s & 0x3) << 5) | (1 & 0x1); 242e7d23d0eSVijay Khemka 243e7d23d0eSVijay Khemka // Last Power Event 244e7d23d0eSVijay Khemka // [7..5] – reserved 245e7d23d0eSVijay Khemka // [4] – 1b = last ‘Power is on’ state was entered via IPMI command 246e7d23d0eSVijay Khemka // [3] – 1b = last power down caused by power fault 247e7d23d0eSVijay Khemka // [2] – 1b = last power down caused by a power interlock being activated 248e7d23d0eSVijay Khemka // [1] – 1b = last power down caused by a Power overload 249e7d23d0eSVijay Khemka // [0] – 1b = AC failed 250e7d23d0eSVijay Khemka // set to 0x0, for we don't support these fields. 251e7d23d0eSVijay Khemka 252e7d23d0eSVijay Khemka chassis_status.last_power_event = 0; 253e7d23d0eSVijay Khemka 254e7d23d0eSVijay Khemka // Misc. Chassis State 255e7d23d0eSVijay Khemka // [7] – reserved 256e7d23d0eSVijay Khemka // [6] – 1b = Chassis Identify command and state info supported (Optional) 257e7d23d0eSVijay Khemka // 0b = Chassis Identify command support unspecified via this command. 258e7d23d0eSVijay Khemka // (The Get Command Support command , if implemented, would still 259e7d23d0eSVijay Khemka // indicate support for the Chassis Identify command) 260e7d23d0eSVijay Khemka // [5..4] – Chassis Identify State. Mandatory when bit[6] =1b, reserved 261e7d23d0eSVijay Khemka // (return 262e7d23d0eSVijay Khemka // as 00b) otherwise. Returns the present chassis identify state. 263e7d23d0eSVijay Khemka // Refer to the Chassis Identify command for more info. 264e7d23d0eSVijay Khemka // 00b = chassis identify state = Off 265e7d23d0eSVijay Khemka // 01b = chassis identify state = Temporary(timed) On 266e7d23d0eSVijay Khemka // 10b = chassis identify state = Indefinite On 267e7d23d0eSVijay Khemka // 11b = reserved 268e7d23d0eSVijay Khemka // [3] – 1b = Cooling/fan fault detected 269e7d23d0eSVijay Khemka // [2] – 1b = Drive Fault 270e7d23d0eSVijay Khemka // [1] – 1b = Front Panel Lockout active (power off and reset via chassis 271e7d23d0eSVijay Khemka // push-buttons disabled.) 272e7d23d0eSVijay Khemka // [0] – 1b = Chassis Intrusion active 273e7d23d0eSVijay Khemka // set to 0, for we don't support them. 274e7d23d0eSVijay Khemka chassis_status.misc_power_state = 0x40; 275e7d23d0eSVijay Khemka 276e7d23d0eSVijay Khemka // Front Panel Button Capabilities and disable/enable status(Optional) 277e7d23d0eSVijay Khemka // set to 0, for we don't support them. 278e7d23d0eSVijay Khemka chassis_status.front_panel_button_cap_status = 0; 279e7d23d0eSVijay Khemka 280e7d23d0eSVijay Khemka // Pack the actual response 281e7d23d0eSVijay Khemka std::memcpy(response, &chassis_status, *data_len); 282e7d23d0eSVijay Khemka 283e7d23d0eSVijay Khemka return IPMI_CC_OK; 284e7d23d0eSVijay Khemka } 285e7d23d0eSVijay Khemka 286e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 287e7d23d0eSVijay Khemka // Get Debug Frame Info 288e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 289e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetFrameInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 290e7d23d0eSVijay Khemka ipmi_request_t request, 291e7d23d0eSVijay Khemka ipmi_response_t response, 292e7d23d0eSVijay Khemka ipmi_data_len_t data_len, 293e7d23d0eSVijay Khemka ipmi_context_t context) 294e7d23d0eSVijay Khemka { 295e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 296e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 297e7d23d0eSVijay Khemka uint8_t num_frames = 3; 298e7d23d0eSVijay Khemka 299e7d23d0eSVijay Khemka std::memcpy(res, req, SIZE_IANA_ID); // IANA ID 300e7d23d0eSVijay Khemka res[SIZE_IANA_ID] = num_frames; 301e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID + 1; 302e7d23d0eSVijay Khemka 303e7d23d0eSVijay Khemka return IPMI_CC_OK; 304e7d23d0eSVijay Khemka } 305e7d23d0eSVijay Khemka 306e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 307e7d23d0eSVijay Khemka // Get Debug Updated Frames 308e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 309e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetUpdFrames(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 310e7d23d0eSVijay Khemka ipmi_request_t request, 311e7d23d0eSVijay Khemka ipmi_response_t response, 312e7d23d0eSVijay Khemka ipmi_data_len_t data_len, 313e7d23d0eSVijay Khemka ipmi_context_t context) 314e7d23d0eSVijay Khemka { 315e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 316e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 317e7d23d0eSVijay Khemka uint8_t num_updates = 3; 318e7d23d0eSVijay Khemka *data_len = 4; 319e7d23d0eSVijay Khemka 320e7d23d0eSVijay Khemka std::memcpy(res, req, SIZE_IANA_ID); // IANA ID 321e7d23d0eSVijay Khemka res[SIZE_IANA_ID] = num_updates; 322e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID + num_updates + 1; 323e7d23d0eSVijay Khemka res[SIZE_IANA_ID + 1] = 1; // info page update 324e7d23d0eSVijay Khemka res[SIZE_IANA_ID + 2] = 2; // cri sel update 325e7d23d0eSVijay Khemka res[SIZE_IANA_ID + 3] = 3; // cri sensor update 326e7d23d0eSVijay Khemka 327e7d23d0eSVijay Khemka return IPMI_CC_OK; 328e7d23d0eSVijay Khemka } 329e7d23d0eSVijay Khemka 330e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 331e7d23d0eSVijay Khemka // Get Debug POST Description 332e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 333e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetPostDesc(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 334e7d23d0eSVijay Khemka ipmi_request_t request, 335e7d23d0eSVijay Khemka ipmi_response_t response, 336e7d23d0eSVijay Khemka ipmi_data_len_t data_len, 337e7d23d0eSVijay Khemka ipmi_context_t context) 338e7d23d0eSVijay Khemka { 339e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 340e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 341e7d23d0eSVijay Khemka uint8_t index = 0; 342e7d23d0eSVijay Khemka uint8_t next = 0; 343e7d23d0eSVijay Khemka uint8_t end = 0; 344e7d23d0eSVijay Khemka uint8_t phase = 0; 345e7d23d0eSVijay Khemka uint8_t count = 0; 346e7d23d0eSVijay Khemka int ret; 347e7d23d0eSVijay Khemka 348e7d23d0eSVijay Khemka index = req[3]; 349e7d23d0eSVijay Khemka phase = req[4]; 350e7d23d0eSVijay Khemka 351e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::INFO>( 352e7d23d0eSVijay Khemka "Get POST Description Event"); 353e7d23d0eSVijay Khemka 354e7d23d0eSVijay Khemka ret = plat_udbg_get_post_desc(index, &next, phase, &end, &count, &res[8]); 355e7d23d0eSVijay Khemka if (ret) 356e7d23d0eSVijay Khemka { 357e7d23d0eSVijay Khemka memcpy(res, req, SIZE_IANA_ID); // IANA ID 358e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID; 359e7d23d0eSVijay Khemka return IPMI_CC_UNSPECIFIED_ERROR; 360e7d23d0eSVijay Khemka } 361e7d23d0eSVijay Khemka 362e7d23d0eSVijay Khemka memcpy(res, req, SIZE_IANA_ID); // IANA ID 363e7d23d0eSVijay Khemka res[3] = index; 364e7d23d0eSVijay Khemka res[4] = next; 365e7d23d0eSVijay Khemka res[5] = phase; 366e7d23d0eSVijay Khemka res[6] = end; 367e7d23d0eSVijay Khemka res[7] = count; 368e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID + 5 + count; 369e7d23d0eSVijay Khemka 370e7d23d0eSVijay Khemka return IPMI_CC_OK; 371e7d23d0eSVijay Khemka } 372e7d23d0eSVijay Khemka 373e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 374e7d23d0eSVijay Khemka // Get Debug GPIO Description 375e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 376e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetGpioDesc(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 377e7d23d0eSVijay Khemka ipmi_request_t request, 378e7d23d0eSVijay Khemka ipmi_response_t response, 379e7d23d0eSVijay Khemka ipmi_data_len_t data_len, 380e7d23d0eSVijay Khemka ipmi_context_t context) 381e7d23d0eSVijay Khemka { 382e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 383e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 384e7d23d0eSVijay Khemka 385e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::INFO>( 386e7d23d0eSVijay Khemka "Get GPIO Description Event"); 387e7d23d0eSVijay Khemka 388e7d23d0eSVijay Khemka std::memcpy(res, req, SIZE_IANA_ID + 1); // IANA ID 389e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID + 1; 390e7d23d0eSVijay Khemka 391e7d23d0eSVijay Khemka return IPMI_CC_OK; 392e7d23d0eSVijay Khemka } 393e7d23d0eSVijay Khemka 394e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 395e7d23d0eSVijay Khemka // Get Debug Frame Data 396e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 397e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetFrameData(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 398e7d23d0eSVijay Khemka ipmi_request_t request, 399e7d23d0eSVijay Khemka ipmi_response_t response, 400e7d23d0eSVijay Khemka ipmi_data_len_t data_len, 401e7d23d0eSVijay Khemka ipmi_context_t context) 402e7d23d0eSVijay Khemka { 403e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 404e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 405e7d23d0eSVijay Khemka uint8_t frame; 406e7d23d0eSVijay Khemka uint8_t page; 407e7d23d0eSVijay Khemka uint8_t next; 408e7d23d0eSVijay Khemka uint8_t count; 409e7d23d0eSVijay Khemka int ret; 410e7d23d0eSVijay Khemka 411e7d23d0eSVijay Khemka frame = req[3]; 412e7d23d0eSVijay Khemka page = req[4]; 413e7d23d0eSVijay Khemka int fr = frame; 414e7d23d0eSVijay Khemka int pg = page; 415e7d23d0eSVijay Khemka 416e7d23d0eSVijay Khemka ret = plat_udbg_get_frame_data(frame, page, &next, &count, &res[7]); 417e7d23d0eSVijay Khemka if (ret) 418e7d23d0eSVijay Khemka { 419e7d23d0eSVijay Khemka memcpy(res, req, SIZE_IANA_ID); // IANA ID 420e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID; 421e7d23d0eSVijay Khemka return IPMI_CC_UNSPECIFIED_ERROR; 422e7d23d0eSVijay Khemka } 423e7d23d0eSVijay Khemka 424e7d23d0eSVijay Khemka memcpy(res, req, SIZE_IANA_ID); // IANA ID 425e7d23d0eSVijay Khemka res[3] = frame; 426e7d23d0eSVijay Khemka res[4] = page; 427e7d23d0eSVijay Khemka res[5] = next; 428e7d23d0eSVijay Khemka res[6] = count; 429e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID + 4 + count; 430e7d23d0eSVijay Khemka 431e7d23d0eSVijay Khemka return IPMI_CC_OK; 432e7d23d0eSVijay Khemka } 433e7d23d0eSVijay Khemka 434e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 435e7d23d0eSVijay Khemka // Get Debug Control Panel 436e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 437e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetCtrlPanel(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 438e7d23d0eSVijay Khemka ipmi_request_t request, 439e7d23d0eSVijay Khemka ipmi_response_t response, 440e7d23d0eSVijay Khemka ipmi_data_len_t data_len, 441e7d23d0eSVijay Khemka ipmi_context_t context) 442e7d23d0eSVijay Khemka { 443e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 444e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 445e7d23d0eSVijay Khemka 446e7d23d0eSVijay Khemka uint8_t panel; 447e7d23d0eSVijay Khemka uint8_t operation; 448e7d23d0eSVijay Khemka uint8_t item; 449e7d23d0eSVijay Khemka uint8_t count; 450e7d23d0eSVijay Khemka ipmi_ret_t ret; 451e7d23d0eSVijay Khemka 452e7d23d0eSVijay Khemka panel = req[3]; 453e7d23d0eSVijay Khemka operation = req[4]; 454e7d23d0eSVijay Khemka item = req[5]; 455e7d23d0eSVijay Khemka 456e7d23d0eSVijay Khemka ret = plat_udbg_control_panel(panel, operation, item, &count, &res[3]); 457e7d23d0eSVijay Khemka 458e7d23d0eSVijay Khemka std::memcpy(res, req, SIZE_IANA_ID); // IANA ID 459e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID + count; 460e7d23d0eSVijay Khemka 461e7d23d0eSVijay Khemka return ret; 462e7d23d0eSVijay Khemka } 463e7d23d0eSVijay Khemka 464e7d23d0eSVijay Khemka // Todo: Need to implement all below functions for oem commands 465e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 466e7d23d0eSVijay Khemka // Set Dimm Info (CMD_OEM_SET_DIMM_INFO) 467e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 468e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetDimmInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 469e7d23d0eSVijay Khemka ipmi_request_t request, ipmi_response_t response, 470e7d23d0eSVijay Khemka ipmi_data_len_t data_len, ipmi_context_t context) 471e7d23d0eSVijay Khemka { 472e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 473e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 474e7d23d0eSVijay Khemka 475e7d23d0eSVijay Khemka std::memcpy(res, req, SIZE_IANA_ID + 1); // IANA ID 476e7d23d0eSVijay Khemka *data_len = SIZE_IANA_ID + 1; 477e7d23d0eSVijay Khemka *data_len = 0; 478e7d23d0eSVijay Khemka 479e7d23d0eSVijay Khemka return IPMI_CC_OK; 480e7d23d0eSVijay Khemka } 481e7d23d0eSVijay Khemka 482e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 483e7d23d0eSVijay Khemka // Get Boot Order (CMD_OEM_GET_BOOT_ORDER) 484e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 485e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemGetBootOrder(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 486e7d23d0eSVijay Khemka ipmi_request_t request, ipmi_response_t response, 487e7d23d0eSVijay Khemka ipmi_data_len_t data_len, ipmi_context_t context) 488e7d23d0eSVijay Khemka { 489e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 490e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 491e7d23d0eSVijay Khemka 492e7d23d0eSVijay Khemka *res++ = 0x01; 493e7d23d0eSVijay Khemka *res++ = 0x00; 494e7d23d0eSVijay Khemka *res++ = 0x09; 495e7d23d0eSVijay Khemka *res++ = 0x02; 496e7d23d0eSVijay Khemka *res++ = 0x03; 497e7d23d0eSVijay Khemka *res++ = 0xff; 498e7d23d0eSVijay Khemka *data_len = 6; 499e7d23d0eSVijay Khemka 500e7d23d0eSVijay Khemka return IPMI_CC_OK; 501e7d23d0eSVijay Khemka } 502e7d23d0eSVijay Khemka 503e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 504e7d23d0eSVijay Khemka // Set Machine Config Info (CMD_OEM_SET_MACHINE_CONFIG_INFO) 505e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 506e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetMachineCfgInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 507e7d23d0eSVijay Khemka ipmi_request_t request, 508e7d23d0eSVijay Khemka ipmi_response_t response, 509e7d23d0eSVijay Khemka ipmi_data_len_t data_len, 510e7d23d0eSVijay Khemka ipmi_context_t context) 511e7d23d0eSVijay Khemka { 512e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 513e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 514e7d23d0eSVijay Khemka 515e7d23d0eSVijay Khemka *data_len = 0; 516e7d23d0eSVijay Khemka 517e7d23d0eSVijay Khemka return IPMI_CC_OK; 518e7d23d0eSVijay Khemka } 519e7d23d0eSVijay Khemka 520e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 521e7d23d0eSVijay Khemka // Set POST start (CMD_OEM_SET_POST_START) 522e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 523e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetPostStart(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 524e7d23d0eSVijay Khemka ipmi_request_t request, ipmi_response_t response, 525e7d23d0eSVijay Khemka ipmi_data_len_t data_len, ipmi_context_t context) 526e7d23d0eSVijay Khemka { 527e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 528e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 529e7d23d0eSVijay Khemka 530e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::INFO>("POST Start Event"); 531e7d23d0eSVijay Khemka 532e7d23d0eSVijay Khemka *data_len = 0; 533e7d23d0eSVijay Khemka return IPMI_CC_OK; 534e7d23d0eSVijay Khemka } 535e7d23d0eSVijay Khemka 536e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 537e7d23d0eSVijay Khemka // Set POST End (CMD_OEM_SET_POST_END) 538e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 539e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetPostEnd(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 540e7d23d0eSVijay Khemka ipmi_request_t request, ipmi_response_t response, 541e7d23d0eSVijay Khemka ipmi_data_len_t data_len, ipmi_context_t context) 542e7d23d0eSVijay Khemka { 543e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 544e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 545e7d23d0eSVijay Khemka 546e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::INFO>("POST End Event"); 547e7d23d0eSVijay Khemka 548e7d23d0eSVijay Khemka *data_len = 0; 549e7d23d0eSVijay Khemka return IPMI_CC_OK; 550e7d23d0eSVijay Khemka } 551e7d23d0eSVijay Khemka 552e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 553e7d23d0eSVijay Khemka // Set Bios Flash Info (CMD_OEM_SET_BIOS_FLASH_INFO) 554e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 555e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetBiosFlashInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 556e7d23d0eSVijay Khemka ipmi_request_t request, 557e7d23d0eSVijay Khemka ipmi_response_t response, 558e7d23d0eSVijay Khemka ipmi_data_len_t data_len, 559e7d23d0eSVijay Khemka ipmi_context_t context) 560e7d23d0eSVijay Khemka { 561e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 562e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 563e7d23d0eSVijay Khemka 564e7d23d0eSVijay Khemka *data_len = 0; 565e7d23d0eSVijay Khemka return IPMI_CC_OK; 566e7d23d0eSVijay Khemka } 567e7d23d0eSVijay Khemka 568e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 569e7d23d0eSVijay Khemka // Set PPR (CMD_OEM_SET_PPR) 570e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 571e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetPpr(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 572e7d23d0eSVijay Khemka ipmi_request_t request, ipmi_response_t response, 573e7d23d0eSVijay Khemka ipmi_data_len_t data_len, ipmi_context_t context) 574e7d23d0eSVijay Khemka { 575e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 576e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 577e7d23d0eSVijay Khemka 578e7d23d0eSVijay Khemka *data_len = 0; 579e7d23d0eSVijay Khemka return IPMI_CC_OK; 580e7d23d0eSVijay Khemka } 581e7d23d0eSVijay Khemka 582e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 583e7d23d0eSVijay Khemka // Get PPR (CMD_OEM_GET_PPR) 584e7d23d0eSVijay Khemka //---------------------------------------------------------------------- 585e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemGetPpr(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 586e7d23d0eSVijay Khemka ipmi_request_t request, ipmi_response_t response, 587e7d23d0eSVijay Khemka ipmi_data_len_t data_len, ipmi_context_t context) 588e7d23d0eSVijay Khemka { 589e7d23d0eSVijay Khemka uint8_t *req = reinterpret_cast<uint8_t *>(request); 590e7d23d0eSVijay Khemka uint8_t *res = reinterpret_cast<uint8_t *>(response); 591e7d23d0eSVijay Khemka 592e7d23d0eSVijay Khemka res[0] = 0x00; 593e7d23d0eSVijay Khemka *data_len = 1; 594e7d23d0eSVijay Khemka 595e7d23d0eSVijay Khemka return IPMI_CC_OK; 596e7d23d0eSVijay Khemka } 597e7d23d0eSVijay Khemka 598e7d23d0eSVijay Khemka static void registerOEMFunctions(void) 599e7d23d0eSVijay Khemka { 600e7d23d0eSVijay Khemka phosphor::logging::log<phosphor::logging::level::INFO>( 601e7d23d0eSVijay Khemka "Registering OEM commands"); 602e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_CHASSIS, 1, NULL, ipmiGetChassisStatus, 603e7d23d0eSVijay Khemka PRIVILEGE_USER); // get chassis status 604e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_INFO, 605e7d23d0eSVijay Khemka NULL, ipmiOemDbgGetFrameInfo, 606e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug frame info 607e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, 608e7d23d0eSVijay Khemka CMD_OEM_USB_DBG_GET_UPDATED_FRAMES, NULL, 609e7d23d0eSVijay Khemka ipmiOemDbgGetUpdFrames, 610e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug updated frames 611e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_POST_DESC, 612e7d23d0eSVijay Khemka NULL, ipmiOemDbgGetPostDesc, 613e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug post description 614e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_GPIO_DESC, 615e7d23d0eSVijay Khemka NULL, ipmiOemDbgGetGpioDesc, 616e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug gpio description 617e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_DATA, 618e7d23d0eSVijay Khemka NULL, ipmiOemDbgGetFrameData, 619e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug frame data 620e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_CTRL_PANEL, 621e7d23d0eSVijay Khemka NULL, ipmiOemDbgGetCtrlPanel, 622e7d23d0eSVijay Khemka PRIVILEGE_USER); // get debug control panel 623e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_DIMM_INFO, NULL, 624e7d23d0eSVijay Khemka ipmiOemSetDimmInfo, 625e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set Dimm Info 626e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_BOOT_ORDER, NULL, 627e7d23d0eSVijay Khemka ipmiOemGetBootOrder, 628e7d23d0eSVijay Khemka PRIVILEGE_USER); // Get Boot Order 629e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_MACHINE_CONFIG_INFO, NULL, 630e7d23d0eSVijay Khemka ipmiOemSetMachineCfgInfo, 631e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set Machine Config Info 632e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_START, NULL, 633e7d23d0eSVijay Khemka ipmiOemSetPostStart, 634e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set POST start 635e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_END, NULL, 636e7d23d0eSVijay Khemka ipmiOemSetPostEnd, 637e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set POST End 638e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_BIOS_FLASH_INFO, NULL, 639e7d23d0eSVijay Khemka ipmiOemSetBiosFlashInfo, 640e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set Bios Flash Info 641e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPR, NULL, ipmiOemSetPpr, 642e7d23d0eSVijay Khemka PRIVILEGE_USER); // Set PPR 643e7d23d0eSVijay Khemka ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_PPR, NULL, ipmiOemGetPpr, 644e7d23d0eSVijay Khemka PRIVILEGE_USER); // Get PPR 645e7d23d0eSVijay Khemka return; 646e7d23d0eSVijay Khemka } 647e7d23d0eSVijay Khemka 648e7d23d0eSVijay Khemka } // namespace ipmi 649