1 #include "systemintfcmds.h" 2 #include "host-ipmid/ipmid-api.h" 3 4 #include <stdio.h> 5 6 void register_netfn_app_functions() __attribute__((constructor)); 7 8 //------------------------------------------------------------------- 9 // Called by Host post response from Get_Message_Flags 10 //------------------------------------------------------------------- 11 ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 12 ipmi_request_t request, ipmi_response_t response, 13 ipmi_data_len_t data_len, ipmi_context_t context) 14 { 15 ipmi_ret_t rc = IPMI_CC_OK; 16 printf("IPMI APP READ EVENT command received\n"); 17 18 // TODO : For now, this is catering only to the Soft Power Off via OEM SEL 19 // mechanism. If we need to make this generically used for some 20 // other conditions, then we can take advantage of context pointer. 21 22 struct oem_sel_timestamped soft_off = {0}; 23 *data_len = sizeof(struct oem_sel_timestamped); 24 25 // either id[0] -or- id[1] can be filled in. We will use id[0] 26 soft_off.id[0] = SEL_OEM_ID_0; 27 soft_off.id[1] = SEL_OEM_ID_0; 28 soft_off.type = SEL_RECORD_TYPE_OEM; 29 30 // Following 3 bytes are from IANA Manufactre_Id field. See below 31 soft_off.manuf_id[0]= 0x41; 32 soft_off.manuf_id[1]= 0xA7; 33 soft_off.manuf_id[2]= 0x00; 34 35 // per IPMI spec NetFuntion for OEM 36 soft_off.netfun = 0x3A; 37 38 // Mechanism to kick start soft shutdown. 39 soft_off.cmd = CMD_POWER; 40 soft_off.data[0] = SOFT_OFF; 41 42 // All '0xFF' since unused. 43 memset(&soft_off.data[1], 0xFF, 3); 44 45 // Pack the actual response 46 memcpy(response, &soft_off, *data_len); 47 return rc; 48 } 49 50 //--------------------------------------------------------------------- 51 // Called by Host on seeing a SMS_ATN bit set. Return a hardcoded 52 // value of 0x2 indicating we need Host read some data. 53 //------------------------------------------------------------------- 54 ipmi_ret_t ipmi_app_get_msg_flags(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 55 ipmi_request_t request, ipmi_response_t response, 56 ipmi_data_len_t data_len, ipmi_context_t context) 57 { 58 // Generic return from IPMI commands. 59 ipmi_ret_t rc = IPMI_CC_OK; 60 61 printf("IPMI APP GET MSG FLAGS returning with [bit:2] set\n"); 62 63 // From IPMI spec V2.0 for Get Message Flags Command : 64 // bit:[1] from LSB : 1b = Event Message Buffer Full. 65 // Return as 0 if Event Message Buffer is not supported, 66 // or when the Event Message buffer is disabled. 67 // TODO. For now. assume its not disabled and send "0x2" anyway: 68 69 uint8_t set_event_msg_buffer_full = 0x2; 70 *data_len = sizeof(set_event_msg_buffer_full); 71 72 // Pack the actual response 73 memcpy(response, &set_event_msg_buffer_full, *data_len); 74 75 return rc; 76 } 77 78 ipmi_ret_t ipmi_app_set_bmc_global_enables(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 79 ipmi_request_t request, ipmi_response_t response, 80 ipmi_data_len_t data_len, ipmi_context_t context) 81 { 82 ipmi_ret_t rc = IPMI_CC_OK; 83 *data_len = 0; 84 85 // Event and message logging enabled by default so return for now 86 printf("IPMI APP SET BMC GLOBAL ENABLES Ignoring for now\n"); 87 88 return rc; 89 } 90 91 void register_netfn_app_functions() 92 { 93 94 // <Read Event Message Buffer> 95 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_READ_EVENT); 96 ipmi_register_callback(NETFUN_APP, IPMI_CMD_READ_EVENT, NULL, ipmi_app_read_event, 97 SYSTEM_INTERFACE); 98 99 // <Set BMC Global Enables> 100 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, 101 IPMI_CMD_SET_BMC_GLOBAL_ENABLES); 102 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_BMC_GLOBAL_ENABLES, NULL, 103 ipmi_app_set_bmc_global_enables, SYSTEM_INTERFACE); 104 105 // <Get Message Flags> 106 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS); 107 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS, NULL, ipmi_app_get_msg_flags, 108 SYSTEM_INTERFACE); 109 110 return; 111 } 112