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