Blame lib/ipmi_ime.c

Packit d14fb6
/*
Packit d14fb6
 * Copyright (c) 2007 Kontron Canada, Inc.  All Rights Reserved.
Packit d14fb6
 *
Packit d14fb6
 * Base on code from
Packit d14fb6
 * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
Packit d14fb6
 *
Packit d14fb6
 * Redistribution and use in source and binary forms, with or without
Packit d14fb6
 * modification, are permitted provided that the following conditions
Packit d14fb6
 * are met:
Packit d14fb6
 *
Packit d14fb6
 * Redistribution of source code must retain the above copyright
Packit d14fb6
 * notice, this list of conditions and the following disclaimer.
Packit d14fb6
 *
Packit d14fb6
 * Redistribution in binary form must reproduce the above copyright
Packit d14fb6
 * notice, this list of conditions and the following disclaimer in the
Packit d14fb6
 * documentation and/or other materials provided with the distribution.
Packit d14fb6
 *
Packit d14fb6
 * Neither the name of Sun Microsystems, Inc. or the names of
Packit d14fb6
 * contributors may be used to endorse or promote products derived
Packit d14fb6
 * from this software without specific prior written permission.
Packit d14fb6
 *
Packit d14fb6
 * This software is provided "AS IS," without a warranty of any kind.
Packit d14fb6
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
Packit d14fb6
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
Packit d14fb6
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
Packit d14fb6
 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
Packit d14fb6
 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
Packit d14fb6
 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
Packit d14fb6
 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
Packit d14fb6
 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
Packit d14fb6
 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
Packit d14fb6
 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
Packit d14fb6
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
Packit d14fb6
 */
Packit d14fb6
Packit d14fb6
/****************************************************************************
Packit d14fb6
*
Packit d14fb6
*       Copyright (c) 2009 Kontron Canada, Inc.  All Rights Reserved.
Packit d14fb6
*
Packit d14fb6
*                              IME
Packit d14fb6
*                    Intel Manageability Engine
Packit d14fb6
*                      Firmware Update Agent
Packit d14fb6
*
Packit d14fb6
* The ME is an IPMI-enabled component included in Intel(R) Next Generation
Packit d14fb6
*  Server Chipset Nehalem-EP platforms.
Packit d14fb6
*
Packit d14fb6
* These are a few synonyms for the ME :
Packit d14fb6
*
Packit d14fb6
* - Dynamic Power Node Manager
Packit d14fb6
* - Intelligent Power Node Manager
Packit d14fb6
* 
Packit d14fb6
* Consult Intel litterature for more information on this technology.
Packit d14fb6
*
Packit d14fb6
* The ME firmware resides on the platform boot flash and contains read only
Packit d14fb6
* boot code for the ME as well as boot image redundancy support. 
Packit d14fb6
*
Packit d14fb6
* This module implements an Upgrade Agent for the ME firwmare. Because the ME 
Packit d14fb6
* implements IPMI command handling, the agent speaks directly to the ME. In other
Packit d14fb6
* words, in order the reach the ME, the BMC must implement IPMB bridging.
Packit d14fb6
*
Packit d14fb6
* The update is done through IPMI (this is IPMITOOL right !), not HECI.
Packit d14fb6
*
Packit d14fb6
* Example: ME available at address 0x88 on IPMI channel 8:
Packit d14fb6
*   ipmitool  -m 0x20 -t 0x88 -b 8 ime info
Packit d14fb6
*
Packit d14fb6
* !! WARNING - You MUST use an image provided by your board vendor. - WARNING !!
Packit d14fb6
*
Packit d14fb6
* author:
Packit d14fb6
*  Jean-Michel.Audet@ca.kontron.com
Packit d14fb6
*  Francois.Isabelle@ca.kontron.com
Packit d14fb6
*
Packit d14fb6
*****************************************************************************/
Packit d14fb6
/*
Packit d14fb6
 * HISTORY
Packit d14fb6
 * ===========================================================================
Packit d14fb6
 * 2009-04-20
Packit d14fb6
 *
Packit d14fb6
 * First public release of Kontron
Packit d14fb6
 *
Packit d14fb6
*/
Packit d14fb6
#include <ipmitool/ipmi_ime.h>
Packit d14fb6
#include <ipmitool/log.h>
Packit d14fb6
#include <ipmitool/ipmi_intf.h>
Packit d14fb6
#include <ipmitool/ipmi_mc.h>
Packit d14fb6
#include <ipmitool/helper.h>
Packit d14fb6
#include <ipmitool/ipmi_strings.h>
Packit d14fb6
Packit d14fb6
Packit d14fb6
#undef OUTPUT_DEBUG
Packit d14fb6
Packit d14fb6
#include <stdlib.h>
Packit d14fb6
#include <string.h>
Packit d14fb6
#include <errno.h>
Packit d14fb6
#include <time.h>
Packit d14fb6
Packit d14fb6
static const int IME_SUCCESS              = 0;
Packit d14fb6
static const int IME_ERROR                = -1;
Packit d14fb6
static const int IME_RESTART              = -2;
Packit d14fb6
Packit d14fb6
#define IME_UPGRADE_BUFFER_SIZE           22
Packit d14fb6
#define IME_RETRY_COUNT                   5
Packit d14fb6
Packit d14fb6
typedef struct ImeUpdateImageCtx
Packit d14fb6
{
Packit d14fb6
   uint32_t   size;
Packit d14fb6
   uint8_t *  pData;
Packit d14fb6
   uint8_t    crc8;
Packit d14fb6
}tImeUpdateImageCtx;
Packit d14fb6
Packit d14fb6
typedef enum eImeState
Packit d14fb6
{
Packit d14fb6
   IME_STATE_IDLE                = 0,
Packit d14fb6
   IME_STATE_UPDATE_REQUESTED    = 1,
Packit d14fb6
   IME_STATE_UPDATE_IN_PROGRESS  = 2,
Packit d14fb6
   IME_STATE_SUCCESS             = 3,
Packit d14fb6
   IME_STATE_FAILED              = 4,
Packit d14fb6
   IME_STATE_ROLLED_BACK         = 5,
Packit d14fb6
   IME_STATE_ABORTED             = 6,
Packit d14fb6
   IME_STATE_INIT_FAILED         = 7
Packit d14fb6
} tImeStateEnum;
Packit d14fb6
Packit d14fb6
Packit d14fb6
typedef enum tImeUpdateType
Packit d14fb6
{
Packit d14fb6
   IME_UPDTYPE_NORMAL            = 1,
Packit d14fb6
   IME_UPDTYPE_MANUAL_ROLLBACK   = 3,
Packit d14fb6
   IME_UPDTYPE_ABORT             = 4
Packit d14fb6
} tImeUpdateType;
Packit d14fb6
Packit d14fb6
Packit d14fb6
#ifdef HAVE_PRAGMA_PACK
Packit d14fb6
#pragma pack(1)
Packit d14fb6
#endif
Packit d14fb6
typedef struct sImeStatus {
Packit d14fb6
   uint8_t image_status;
Packit d14fb6
   tImeStateEnum update_state;
Packit d14fb6
   uint8_t update_attempt_status;
Packit d14fb6
   uint8_t rollback_attempt_status;
Packit d14fb6
   uint8_t update_type;
Packit d14fb6
   uint8_t dependent_flag;
Packit d14fb6
   uint8_t free_area_size[4];
Packit d14fb6
} ATTRIBUTE_PACKING tImeStatus ;
Packit d14fb6
#ifdef HAVE_PRAGMA_PACK
Packit d14fb6
#pragma pack(0)
Packit d14fb6
#endif
Packit d14fb6
Packit d14fb6
#ifdef HAVE_PRAGMA_PACK
Packit d14fb6
#pragma pack(1)
Packit d14fb6
#endif
Packit d14fb6
typedef struct sImeCaps {
Packit d14fb6
   uint8_t area_supported;
Packit d14fb6
   uint8_t special_caps;
Packit d14fb6
} ATTRIBUTE_PACKING tImeCaps ;
Packit d14fb6
#ifdef HAVE_PRAGMA_PACK
Packit d14fb6
#pragma pack(0)
Packit d14fb6
#endif
Packit d14fb6
Packit d14fb6
Packit d14fb6
static void ImePrintUsage(void);
Packit d14fb6
static int  ImeGetInfo(struct ipmi_intf *intf);
Packit d14fb6
static int  ImeUpgrade(struct ipmi_intf *intf, char* imageFilename);
Packit d14fb6
static int  ImeManualRollback(struct ipmi_intf *intf);
Packit d14fb6
static int  ImeUpdatePrepare(struct ipmi_intf *intf);
Packit d14fb6
static int  ImeUpdateOpenArea(struct ipmi_intf *intf);
Packit d14fb6
static int  ImeUpdateWriteArea(
Packit d14fb6
                              struct ipmi_intf *intf,
Packit d14fb6
                              uint8_t sequence, 
Packit d14fb6
                              uint8_t length, 
Packit d14fb6
                              uint8_t * pBuf
Packit d14fb6
                          );
Packit d14fb6
static int  ImeUpdateCloseArea(
Packit d14fb6
                              struct ipmi_intf *intf,
Packit d14fb6
                              uint32_t size, 
Packit d14fb6
                              uint16_t checksum
Packit d14fb6
                          );
Packit d14fb6
Packit d14fb6
static int ImeUpdateGetStatus(struct ipmi_intf *intf, tImeStatus *pStatus);
Packit d14fb6
static int ImeUpdateGetCapabilities(struct ipmi_intf *intf, tImeCaps *pCaps );
Packit d14fb6
static int  ImeUpdateRegisterUpdate(struct ipmi_intf *intf, tImeUpdateType type);
Packit d14fb6
Packit d14fb6
static int  ImeImageCtxFromFile(
Packit d14fb6
                                 char * imageFilename, 
Packit d14fb6
                                 tImeUpdateImageCtx * pImageCtx);
Packit d14fb6
static int ImeUpdateShowStatus(struct ipmi_intf *intf);
Packit d14fb6
Packit d14fb6
static uint8_t ImeCrc8( uint32_t length, uint8_t * pBuf );
Packit d14fb6
Packit d14fb6
Packit d14fb6
static int ImeGetInfo(struct ipmi_intf *intf)
Packit d14fb6
{
Packit d14fb6
   int rc = IME_ERROR;
Packit d14fb6
   struct ipmi_rs * rsp;
Packit d14fb6
   struct ipmi_rq req;
Packit d14fb6
   struct ipm_devid_rsp *devid;
Packit d14fb6
   const char *product=NULL;
Packit d14fb6
   tImeStatus status;
Packit d14fb6
   tImeCaps caps;
Packit d14fb6
Packit d14fb6
   memset(&req, 0, sizeof(req));
Packit d14fb6
   req.msg.netfn = IPMI_NETFN_APP;
Packit d14fb6
   req.msg.cmd = BMC_GET_DEVICE_ID;
Packit d14fb6
   req.msg.data_len = 0;
Packit d14fb6
Packit d14fb6
   rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
   if (rsp == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "Get Device ID command failed");
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
   if (rsp->ccode > 0) {
Packit d14fb6
      lprintf(LOG_ERR, "Get Device ID command failed: %s",
Packit d14fb6
         val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   devid = (struct ipm_devid_rsp *) rsp->data;
Packit d14fb6
Packit d14fb6
   lprintf(LOG_DEBUG,"Device ID                 : %i", devid->device_id);
Packit d14fb6
   lprintf(LOG_DEBUG,"Device Revision           : %i",
Packit d14fb6
                           devid->device_revision & IPM_DEV_DEVICE_ID_REV_MASK);
Packit d14fb6
Packit d14fb6
   if(
Packit d14fb6
      (devid->device_id == 0)
Packit d14fb6
      &&
Packit d14fb6
      ((devid->device_revision & IPM_DEV_DEVICE_ID_REV_MASK) == 0)
Packit d14fb6
      &&
Packit d14fb6
      (
Packit d14fb6
         (devid->manufacturer_id[0] == 0x57) // Intel
Packit d14fb6
         &&
Packit d14fb6
         (devid->manufacturer_id[1] == 0x01) // Intel
Packit d14fb6
         &&
Packit d14fb6
         (devid->manufacturer_id[2] == 0x00) // Intel
Packit d14fb6
      )
Packit d14fb6
      &&
Packit d14fb6
      (
Packit d14fb6
         (devid->product_id[1] == 0x0b)
Packit d14fb6
         &&
Packit d14fb6
         (devid->product_id[0] == 0x00)
Packit d14fb6
      )
Packit d14fb6
     )
Packit d14fb6
   {
Packit d14fb6
      rc = IME_SUCCESS;
Packit d14fb6
      printf("Manufacturer Name          : %s\n",
Packit d14fb6
               val2str( (long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id), 
Packit d14fb6
               ipmi_oem_info) );
Packit d14fb6
Packit d14fb6
      printf("Product ID                 : %u (0x%02x%02x)\n",
Packit d14fb6
         buf2short((uint8_t *)(devid->product_id)),
Packit d14fb6
         devid->product_id[1], devid->product_id[0]);
Packit d14fb6
 
Packit d14fb6
      product=oemval2str(IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id),
Packit d14fb6
                      (devid->product_id[1]<<8)+devid->product_id[0],
Packit d14fb6
                      ipmi_oem_product_info);
Packit d14fb6
Packit d14fb6
      if (product!=NULL) 
Packit d14fb6
      {
Packit d14fb6
         printf("Product Name               : %s\n", product);
Packit d14fb6
      }
Packit d14fb6
Packit d14fb6
      printf("Intel ME Firmware Revision : %x.%02x.%02x.%x%x%x.%x\n",
Packit d14fb6
            ((devid->fw_rev1 & IPM_DEV_FWREV1_MAJOR_MASK )         ),
Packit d14fb6
            ((devid->fw_rev2                             ) >>     4),
Packit d14fb6
            ((devid->fw_rev2                             )  &  0x0f),
Packit d14fb6
            ((devid->aux_fw_rev[1]                       ) >>     4),
Packit d14fb6
            ((devid->aux_fw_rev[1]                       )  &  0x0f),
Packit d14fb6
            ((devid->aux_fw_rev[2]                       ) >>     4),
Packit d14fb6
            ((devid->aux_fw_rev[2]                       )  &  0x0f)
Packit d14fb6
      );
Packit d14fb6
Packit d14fb6
      printf("SPS FW IPMI cmd version    : %x.%x\n",
Packit d14fb6
         devid->aux_fw_rev[0] >>     4,
Packit d14fb6
         devid->aux_fw_rev[0] &  0x0f);
Packit d14fb6
Packit d14fb6
      lprintf(LOG_DEBUG,"Flags: %xh", devid->aux_fw_rev[3]);
Packit d14fb6
Packit d14fb6
      printf("Current Image Type         : ");
Packit d14fb6
      switch( (devid->aux_fw_rev[3] & 0x03) )
Packit d14fb6
      {
Packit d14fb6
         case 0:
Packit d14fb6
            printf("Recovery\n");
Packit d14fb6
         break;
Packit d14fb6
Packit d14fb6
         case 1:
Packit d14fb6
            printf("Operational Image 1\n");
Packit d14fb6
         break;
Packit d14fb6
Packit d14fb6
         case 2:
Packit d14fb6
            printf("Operational Image 2\n");
Packit d14fb6
         break;
Packit d14fb6
Packit d14fb6
         case 3:
Packit d14fb6
         default:
Packit d14fb6
            printf("Unknown\n");
Packit d14fb6
         break;
Packit d14fb6
      }
Packit d14fb6
   }
Packit d14fb6
   else
Packit d14fb6
   {
Packit d14fb6
         printf("Supported ME not found\n");
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   if(rc == IME_SUCCESS)
Packit d14fb6
   {
Packit d14fb6
      rc = ImeUpdateGetStatus(intf, &status);
Packit d14fb6
   
Packit d14fb6
      if(rc == IME_SUCCESS)
Packit d14fb6
      {
Packit d14fb6
         rc = ImeUpdateGetCapabilities(intf, &caps);
Packit d14fb6
      }
Packit d14fb6
Packit d14fb6
   }
Packit d14fb6
   
Packit d14fb6
   if(rc == IME_SUCCESS)
Packit d14fb6
   {
Packit d14fb6
      uint8_t newImage  = ((status.image_status >> 1) & 0x01);
Packit d14fb6
      uint8_t rollImage = ((status.image_status >> 2) & 0x01);
Packit d14fb6
      uint8_t runArea   = ((status.image_status >> 3) & 0x03);
Packit d14fb6
      uint8_t rollSup   = ((caps.special_caps   >> 0) & 0x01);
Packit d14fb6
      uint8_t recovSup  = ((caps.special_caps   >> 1) & 0x01);
Packit d14fb6
Packit d14fb6
      uint8_t operSup   = ((caps.area_supported   >> 1) & 0x01);
Packit d14fb6
      uint8_t piaSup    = ((caps.area_supported   >> 2) & 0x01);
Packit d14fb6
      uint8_t sdrSup    = ((caps.area_supported   >> 3) & 0x01);
Packit d14fb6
Packit d14fb6
      printf("\nSupported Area\n");
Packit d14fb6
      printf("   Operation Code          : %s\n", (operSup ? "Supported" : "Unsupported"));
Packit d14fb6
      printf("   PIA                     : %s\n", (piaSup ? "Supported" : "Unsupported"));
Packit d14fb6
      printf("   SDR                     : %s\n", (sdrSup ? "Supported" : "Unsupported"));
Packit d14fb6
Packit d14fb6
      printf("\nSpecial Capabilities\n");
Packit d14fb6
      printf("   Rollback                : %s\n", (rollSup ? "Supported" : "Unsupported"));
Packit d14fb6
      printf("   Recovery                : %s\n", (recovSup ? "Supported" : "Unsupported"));
Packit d14fb6
Packit d14fb6
      printf("\nImage Status\n");
Packit d14fb6
      printf("   Staging (new)           : %s\n", (newImage ? "Valid" : "Invalid"));
Packit d14fb6
      printf("   Rollback                : %s\n", (rollImage ? "Valid" : "Invalid"));
Packit d14fb6
      if(runArea == 0)
Packit d14fb6
         printf("   Running Image Area      : CODE\n");
Packit d14fb6
      else
Packit d14fb6
         printf("   Running Image Area      : CODE%d\n", runArea);
Packit d14fb6
Packit d14fb6
  }
Packit d14fb6
Packit d14fb6
   return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
static int ImeUpgrade(struct ipmi_intf *intf, char* imageFilename)
Packit d14fb6
{
Packit d14fb6
   int rc = IME_SUCCESS;
Packit d14fb6
   tImeUpdateImageCtx imgCtx;
Packit d14fb6
   tImeStatus imeStatus;
Packit d14fb6
   time_t start,end,current;
Packit d14fb6
   
Packit d14fb6
   time(&start;;
Packit d14fb6
Packit d14fb6
   memset(&imgCtx, 0, sizeof(tImeUpdateImageCtx));
Packit d14fb6
Packit d14fb6
   rc = ImeImageCtxFromFile(imageFilename, &imgCtx);
Packit d14fb6
Packit d14fb6
   if(
Packit d14fb6
      (rc == IME_ERROR) ||
Packit d14fb6
      (imgCtx.pData == NULL) ||
Packit d14fb6
      (imgCtx.size == 0)
Packit d14fb6
     )
Packit d14fb6
   {
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   ImeUpdateGetStatus(intf,&imeStatus);
Packit d14fb6
Packit d14fb6
   if(rc == IME_SUCCESS)
Packit d14fb6
   {
Packit d14fb6
      rc = ImeUpdatePrepare(intf);
Packit d14fb6
      ImeUpdateGetStatus(intf,&imeStatus);
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   if(
Packit d14fb6
      (rc == IME_SUCCESS) &&
Packit d14fb6
      (imeStatus.update_state == IME_STATE_UPDATE_REQUESTED) 
Packit d14fb6
     )
Packit d14fb6
   {
Packit d14fb6
      rc = ImeUpdateOpenArea(intf);
Packit d14fb6
      ImeUpdateGetStatus(intf,&imeStatus);
Packit d14fb6
   }
Packit d14fb6
   else if(rc == IME_SUCCESS)
Packit d14fb6
   {
Packit d14fb6
      lprintf(LOG_ERROR,"ME state error (%i), aborting", imeStatus.update_state);
Packit d14fb6
      rc = IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
Packit d14fb6
   if(
Packit d14fb6
      (rc == IME_SUCCESS) &&
Packit d14fb6
      (imeStatus.update_state == IME_STATE_UPDATE_IN_PROGRESS) 
Packit d14fb6
     )
Packit d14fb6
   {
Packit d14fb6
      uint8_t sequence = 0;
Packit d14fb6
      uint32_t counter = 0;
Packit d14fb6
      uint8_t retry = 0;
Packit d14fb6
      uint8_t shownPercent = 0xff;
Packit d14fb6
Packit d14fb6
      while(   
Packit d14fb6
            (counter < imgCtx.size) && 
Packit d14fb6
            (rc == IME_SUCCESS) &&
Packit d14fb6
            (retry < IME_RETRY_COUNT)
Packit d14fb6
           )
Packit d14fb6
      {
Packit d14fb6
         uint8_t length = IME_UPGRADE_BUFFER_SIZE;
Packit d14fb6
         uint8_t currentPercent;
Packit d14fb6
Packit d14fb6
         if( (imgCtx.size - counter) < IME_UPGRADE_BUFFER_SIZE )
Packit d14fb6
         {
Packit d14fb6
            length = (imgCtx.size - counter);
Packit d14fb6
         }
Packit d14fb6
Packit d14fb6
         rc = ImeUpdateWriteArea(intf,sequence,length,&imgCtx.pData[counter]);
Packit d14fb6
         
Packit d14fb6
         /*
Packit d14fb6
         As per the flowchart Intel Dynamic Power Node Manager 1.5 IPMI Iface
Packit d14fb6
         page 65
Packit d14fb6
         We shall send the GetStatus command each time following a write area
Packit d14fb6
         but this add too much time to the upgrade
Packit d14fb6
         */   
Packit d14fb6
         /*  ImeUpdateGetStatus(intf,&imeStatus); */
Packit d14fb6
         counter += length;
Packit d14fb6
         sequence ++;
Packit d14fb6
Packit d14fb6
Packit d14fb6
         currentPercent = ((float)counter/imgCtx.size)*100;
Packit d14fb6
Packit d14fb6
         if(currentPercent != shownPercent)
Packit d14fb6
         {
Packit d14fb6
            shownPercent = currentPercent;
Packit d14fb6
            printf("Percent: %02i,  ", shownPercent);
Packit d14fb6
            time(¤t;;
Packit d14fb6
            printf("Elapsed time %02ld:%02ld\r",((current-start)/60), ((current-start)%60));
Packit d14fb6
            fflush(stdout);
Packit d14fb6
Packit d14fb6
         }
Packit d14fb6
      }
Packit d14fb6
      ImeUpdateGetStatus(intf,&imeStatus);
Packit d14fb6
      printf("\n");
Packit d14fb6
   }
Packit d14fb6
   else if(rc == IME_SUCCESS)
Packit d14fb6
   {
Packit d14fb6
      lprintf(LOG_ERROR,"ME state error (%i), aborting", imeStatus.update_state);
Packit d14fb6
      rc = IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   if(
Packit d14fb6
      (rc == IME_SUCCESS) &&
Packit d14fb6
      (imeStatus.update_state == IME_STATE_UPDATE_IN_PROGRESS) 
Packit d14fb6
     )
Packit d14fb6
   {
Packit d14fb6
      rc = ImeUpdateCloseArea(intf, imgCtx.size, imgCtx.crc8);
Packit d14fb6
      ImeUpdateGetStatus(intf,&imeStatus);
Packit d14fb6
   }
Packit d14fb6
   else if(rc == IME_SUCCESS)
Packit d14fb6
   {
Packit d14fb6
      lprintf(LOG_ERROR,"ME state error, aborting");
Packit d14fb6
      rc = IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   if(
Packit d14fb6
      (rc == IME_SUCCESS) &&
Packit d14fb6
      (imeStatus.update_state == IME_STATE_UPDATE_REQUESTED) 
Packit d14fb6
     )
Packit d14fb6
   {
Packit d14fb6
      printf("UpdateCompleted, Activate now\n");
Packit d14fb6
      rc = ImeUpdateRegisterUpdate(intf, IME_UPDTYPE_NORMAL);
Packit d14fb6
      ImeUpdateGetStatus(intf,&imeStatus);
Packit d14fb6
   }
Packit d14fb6
   else if(rc == IME_SUCCESS)
Packit d14fb6
   {
Packit d14fb6
      lprintf(LOG_ERROR,"ME state error, aborting");
Packit d14fb6
      rc = IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   if(
Packit d14fb6
      (rc == IME_SUCCESS) &&
Packit d14fb6
      (imeStatus.update_state == IME_STATE_SUCCESS) 
Packit d14fb6
     )
Packit d14fb6
   {
Packit d14fb6
      time(&end;;
Packit d14fb6
      printf("Update Completed in %02ld:%02ld\n",(end-start)/60, (end-start)%60);
Packit d14fb6
   }
Packit d14fb6
   else
Packit d14fb6
   {
Packit d14fb6
      time(&end;;
Packit d14fb6
      printf("Update Error\n");
Packit d14fb6
      printf("\nTime Taken %02ld:%02ld\n",(end-start)/60, (end-start)%60);
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
static int ImeUpdatePrepare(struct ipmi_intf *intf)
Packit d14fb6
{
Packit d14fb6
   struct ipmi_rs * rsp;
Packit d14fb6
   struct ipmi_rq req;
Packit d14fb6
Packit d14fb6
   #ifdef OUTPUT_DEBUG
Packit d14fb6
   printf("ImeUpdatePrepare\n");
Packit d14fb6
   #endif
Packit d14fb6
Packit d14fb6
   memset(&req, 0, sizeof(req));
Packit d14fb6
   req.msg.netfn = 0x30;  // OEM NetFn
Packit d14fb6
   req.msg.cmd = 0xA0;
Packit d14fb6
   req.msg.data_len = 0;
Packit d14fb6
Packit d14fb6
   rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
   if (rsp == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdatePrepare command failed");
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
   if (rsp->ccode > 0) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdatePrepare command failed: %s",
Packit d14fb6
         val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   lprintf(LOG_DEBUG, "UpdatePrepare command succeed");
Packit d14fb6
   return IME_SUCCESS;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int ImeUpdateOpenArea(struct ipmi_intf *intf)
Packit d14fb6
{
Packit d14fb6
   struct ipmi_rs * rsp;
Packit d14fb6
   struct ipmi_rq req;
Packit d14fb6
   uint8_t buffer[ 2 ];
Packit d14fb6
Packit d14fb6
   #ifdef OUTPUT_DEBUG
Packit d14fb6
   printf("ImeUpdateOpenArea\n");
Packit d14fb6
   #endif
Packit d14fb6
Packit d14fb6
   memset(&req, 0, sizeof(req));
Packit d14fb6
   req.msg.netfn = 0x30;  // OEM NetFn
Packit d14fb6
   req.msg.cmd = 0xA1;
Packit d14fb6
Packit d14fb6
   buffer[0] = 0x01; // Area Type : Operational code
Packit d14fb6
   buffer[1] = 0x00; // Reserved : 0
Packit d14fb6
   req.msg.data = buffer;
Packit d14fb6
Packit d14fb6
   req.msg.data_len = 2;
Packit d14fb6
Packit d14fb6
   rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
   if (rsp == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdateOpenArea command failed");
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
   if (rsp->ccode > 0) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdateOpenArea command failed: %s",
Packit d14fb6
         val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   lprintf(LOG_DEBUG, "UpdateOpenArea command succeed");
Packit d14fb6
   return IME_SUCCESS;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int ImeUpdateWriteArea(
Packit d14fb6
                              struct ipmi_intf *intf,
Packit d14fb6
                              uint8_t sequence, 
Packit d14fb6
                              uint8_t length, 
Packit d14fb6
                              uint8_t * pBuf
Packit d14fb6
                          )
Packit d14fb6
{
Packit d14fb6
   struct ipmi_rs * rsp;
Packit d14fb6
   struct ipmi_rq req;
Packit d14fb6
   uint8_t buffer[ IME_UPGRADE_BUFFER_SIZE + 1 ];
Packit d14fb6
Packit d14fb6
//   printf("ImeUpdateWriteArea %i\n", sequence);
Packit d14fb6
Packit d14fb6
   if(length > IME_UPGRADE_BUFFER_SIZE)
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
Packit d14fb6
   buffer[0] = sequence;
Packit d14fb6
   memcpy(&buffer[1], pBuf, length);
Packit d14fb6
Packit d14fb6
   memset(&req, 0, sizeof(req));
Packit d14fb6
   req.msg.netfn = 0x30;  // OEM NetFn
Packit d14fb6
   req.msg.cmd = 0xA2;
Packit d14fb6
   req.msg.data = buffer;
Packit d14fb6
   req.msg.data_len = length + 1;
Packit d14fb6
Packit d14fb6
   rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
   if (rsp == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdateWriteArea command failed");
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
   if (rsp->ccode > 0) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdateWriteArea command failed: %s",
Packit d14fb6
         val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
      if( rsp->ccode == 0x80) // restart operation
Packit d14fb6
         return IME_RESTART;
Packit d14fb6
      else
Packit d14fb6
         return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   lprintf(LOG_DEBUG, "UpdateWriteArea command succeed");
Packit d14fb6
   return IME_SUCCESS;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int ImeUpdateCloseArea(
Packit d14fb6
                              struct ipmi_intf *intf,
Packit d14fb6
                              uint32_t size, 
Packit d14fb6
                              uint16_t checksum
Packit d14fb6
                          )
Packit d14fb6
{
Packit d14fb6
   struct ipmi_rs * rsp;
Packit d14fb6
   struct ipmi_rq req;
Packit d14fb6
   uint8_t length = sizeof( uint32_t ) + sizeof( uint16_t ); 
Packit d14fb6
   uint8_t buffer[ sizeof( uint32_t ) + sizeof( uint16_t ) ];
Packit d14fb6
Packit d14fb6
   #ifdef OUTPUT_DEBUG
Packit d14fb6
   printf( "ImeUpdateCloseArea\n");
Packit d14fb6
   #endif
Packit d14fb6
Packit d14fb6
   buffer[0] = (uint8_t)((size & 0x000000ff) >>  0);
Packit d14fb6
   buffer[1] = (uint8_t)((size & 0x0000ff00) >>  8);
Packit d14fb6
   buffer[2] = (uint8_t)((size & 0x00ff0000) >> 16);
Packit d14fb6
   buffer[3] = (uint8_t)((size & 0xff000000) >> 24);
Packit d14fb6
Packit d14fb6
   buffer[4] = (uint8_t)((checksum & 0x00ff) >>  0);
Packit d14fb6
   buffer[5] = (uint8_t)((checksum & 0xff00) >>  8);
Packit d14fb6
Packit d14fb6
   memset(&req, 0, sizeof(req));
Packit d14fb6
   req.msg.netfn = 0x30;  // OEM NetFn
Packit d14fb6
   req.msg.cmd = 0xA3;
Packit d14fb6
   req.msg.data = buffer;
Packit d14fb6
   req.msg.data_len = length;
Packit d14fb6
Packit d14fb6
   rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
   if (rsp == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdateCloseArea command failed");
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
   if (rsp->ccode > 0) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdateCloseArea command failed: %s",
Packit d14fb6
         val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   lprintf(LOG_DEBUG, "UpdateCloseArea command succeed");
Packit d14fb6
   return IME_SUCCESS;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int ImeUpdateGetStatus(struct ipmi_intf *intf, tImeStatus *pStatus )
Packit d14fb6
{
Packit d14fb6
   struct      ipmi_rs * rsp;
Packit d14fb6
   struct      ipmi_rq req;
Packit d14fb6
   tImeStatus *pGetStatus;
Packit d14fb6
   
Packit d14fb6
   memset(pStatus, 0, sizeof(tImeStatus));
Packit d14fb6
   pStatus->update_state = IME_STATE_ABORTED;
Packit d14fb6
Packit d14fb6
Packit d14fb6
   #ifdef OUTPUT_DEBUG
Packit d14fb6
   printf("ImeUpdateGetStatus: ");
Packit d14fb6
   #endif
Packit d14fb6
Packit d14fb6
   memset(&req, 0, sizeof(req));
Packit d14fb6
   req.msg.netfn = 0x30;  // OEM NetFn
Packit d14fb6
   req.msg.cmd = 0xA6;
Packit d14fb6
   req.msg.data_len = 0;
Packit d14fb6
Packit d14fb6
   rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
   if (rsp == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdatePrepare command failed");
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
   if (rsp->ccode > 0) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdatePrepare command failed: %s",
Packit d14fb6
         val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   lprintf(LOG_DEBUG, "UpdatePrepare command succeed");
Packit d14fb6
Packit d14fb6
   pGetStatus = (tImeStatus *) rsp->data;
Packit d14fb6
   
Packit d14fb6
   memcpy( pStatus, pGetStatus, sizeof(tImeStatus));
Packit d14fb6
Packit d14fb6
   #ifdef OUTPUT_DEBUG
Packit d14fb6
   printf("%x - ", pStatus->updateState);
Packit d14fb6
Packit d14fb6
   switch( pStatus->update_state )
Packit d14fb6
   {
Packit d14fb6
      case IME_STATE_IDLE:
Packit d14fb6
         printf("IDLE\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_UPDATE_REQUESTED:
Packit d14fb6
         printf("Update Requested\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_UPDATE_IN_PROGRESS:
Packit d14fb6
         printf("Update in Progress\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_SUCCESS:
Packit d14fb6
         printf("Update Success\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_FAILED:
Packit d14fb6
         printf("Update Failed\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_ROLLED_BACK:
Packit d14fb6
         printf("Update Rolled Back\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_ABORTED:
Packit d14fb6
         printf("Update Aborted\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_INIT_FAILED:
Packit d14fb6
         printf("Update Init Failed\n");
Packit d14fb6
      break;
Packit d14fb6
      default:
Packit d14fb6
         printf("Unknown, reserved\n");
Packit d14fb6
      break;
Packit d14fb6
   }
Packit d14fb6
   #endif
Packit d14fb6
Packit d14fb6
   return IME_SUCCESS;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int ImeUpdateGetCapabilities(struct ipmi_intf *intf, tImeCaps *pCaps )
Packit d14fb6
{
Packit d14fb6
   struct      ipmi_rs * rsp;
Packit d14fb6
   struct      ipmi_rq req;
Packit d14fb6
   tImeCaps *  pGetCaps;
Packit d14fb6
   
Packit d14fb6
   memset(pCaps, 0, sizeof(tImeCaps));
Packit d14fb6
Packit d14fb6
Packit d14fb6
   #ifdef OUTPUT_DEBUG
Packit d14fb6
   printf("ImeUpdateGetStatus: ");
Packit d14fb6
   #endif
Packit d14fb6
Packit d14fb6
   memset(&req, 0, sizeof(req));
Packit d14fb6
   req.msg.netfn = 0x30;  // OEM NetFn
Packit d14fb6
   req.msg.cmd = 0xA7;
Packit d14fb6
   req.msg.data_len = 0;
Packit d14fb6
Packit d14fb6
   rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
   if (rsp == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdatePrepare command failed");
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
   if (rsp->ccode > 0) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdatePrepare command failed: %s",
Packit d14fb6
         val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   lprintf(LOG_DEBUG, "UpdatePrepare command succeed");
Packit d14fb6
Packit d14fb6
   pGetCaps = (tImeCaps *) rsp->data;
Packit d14fb6
   
Packit d14fb6
   memcpy( pCaps, pGetCaps, sizeof(tImeCaps));
Packit d14fb6
Packit d14fb6
   return IME_SUCCESS;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
static int ImeUpdateRegisterUpdate(struct ipmi_intf *intf, tImeUpdateType type)
Packit d14fb6
{
Packit d14fb6
   struct ipmi_rs * rsp;
Packit d14fb6
   struct ipmi_rq req;
Packit d14fb6
   uint8_t buffer[ 2 ];
Packit d14fb6
Packit d14fb6
   #ifdef OUTPUT_DEBUG
Packit d14fb6
   printf( "ImeUpdateRegisterUpdate\n");
Packit d14fb6
   #endif
Packit d14fb6
Packit d14fb6
   buffer[0] = type;  // Normal Update
Packit d14fb6
   buffer[1] = 0;  // Flags, reserved
Packit d14fb6
Packit d14fb6
   memset(&req, 0, sizeof(req));
Packit d14fb6
   req.msg.netfn = 0x30;  // OEM NetFn
Packit d14fb6
   req.msg.cmd = 0xA4;
Packit d14fb6
   req.msg.data = buffer;
Packit d14fb6
   req.msg.data_len = 2;
Packit d14fb6
Packit d14fb6
   rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
   if (rsp == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "ImeUpdateRegisterUpdate command failed");
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
   if (rsp->ccode > 0) {
Packit d14fb6
      lprintf(LOG_ERR, "ImeUpdateRegisterUpdate command failed: %s",
Packit d14fb6
         val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   lprintf(LOG_DEBUG, "ImeUpdateRegisterUpdate command succeed");
Packit d14fb6
   return IME_SUCCESS;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
Packit d14fb6
Packit d14fb6
static int ImeUpdateShowStatus(struct ipmi_intf *intf)
Packit d14fb6
{
Packit d14fb6
   struct ipmi_rs * rsp;
Packit d14fb6
   struct ipmi_rq req;
Packit d14fb6
   tImeStatus *pStatus;
Packit d14fb6
Packit d14fb6
   printf("ImeUpdateGetStatus: ");
Packit d14fb6
Packit d14fb6
   memset(&req, 0, sizeof(req));
Packit d14fb6
   req.msg.netfn = 0x30;  // OEM NetFn
Packit d14fb6
   req.msg.cmd = 0xA6;
Packit d14fb6
   req.msg.data_len = 0;
Packit d14fb6
Packit d14fb6
   rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
   if (rsp == NULL) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdatePrepare command failed");
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
   if (rsp->ccode > 0) {
Packit d14fb6
      lprintf(LOG_ERR, "UpdatePrepare command failed: %s",
Packit d14fb6
         val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   lprintf(LOG_DEBUG, "UpdatePrepare command succeed");
Packit d14fb6
Packit d14fb6
   pStatus = (tImeStatus *) rsp->data ;
Packit d14fb6
Packit d14fb6
   
Packit d14fb6
   printf("image_status: %x - ", pStatus->image_status);
Packit d14fb6
Packit d14fb6
   printf("update_state: %x - ", pStatus->update_state);
Packit d14fb6
Packit d14fb6
   switch( pStatus->update_state )
Packit d14fb6
   {
Packit d14fb6
      case IME_STATE_IDLE:
Packit d14fb6
         printf("IDLE\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_UPDATE_REQUESTED:
Packit d14fb6
         printf("Update Requested\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_UPDATE_IN_PROGRESS:
Packit d14fb6
         printf("Update in Progress\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_SUCCESS:
Packit d14fb6
         printf("Update Success\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_FAILED:
Packit d14fb6
         printf("Update Failed\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_ROLLED_BACK:
Packit d14fb6
         printf("Update Rolled Back\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_ABORTED:
Packit d14fb6
         printf("Update Aborted\n");
Packit d14fb6
      break;
Packit d14fb6
      case IME_STATE_INIT_FAILED:
Packit d14fb6
         printf("Update Init Failed\n");
Packit d14fb6
      break;
Packit d14fb6
      default:
Packit d14fb6
         printf("Unknown, reserved\n");
Packit d14fb6
      break;
Packit d14fb6
   }
Packit d14fb6
   printf("update_attempt_status  : %x\n", pStatus->update_attempt_status);
Packit d14fb6
   printf("rollback_attempt_status: %x\n", pStatus->rollback_attempt_status);
Packit d14fb6
   printf("update_type            : %x\n", pStatus->update_type);
Packit d14fb6
   printf("dependent_flag         : %x\n", pStatus->dependent_flag);
Packit d14fb6
   printf("free_area_size         : %x\n", pStatus->free_area_size[0]);
Packit d14fb6
   printf("                       : %x\n", pStatus->free_area_size[1]);
Packit d14fb6
   printf("                       : %x\n", pStatus->free_area_size[2]);
Packit d14fb6
   printf("                       : %x\n", pStatus->free_area_size[3]);
Packit d14fb6
Packit d14fb6
   return IME_SUCCESS;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
static int ImeImageCtxFromFile(
Packit d14fb6
                                 char* imageFilename, 
Packit d14fb6
                                 tImeUpdateImageCtx * pImageCtx
Packit d14fb6
                               )
Packit d14fb6
{
Packit d14fb6
   int rc = IME_SUCCESS;
Packit d14fb6
   FILE* pImageFile = fopen(imageFilename, "rb");
Packit d14fb6
   
Packit d14fb6
   if ( pImageFile == NULL )
Packit d14fb6
   {
Packit d14fb6
      lprintf(LOG_NOTICE,"Cannot open image file %s", imageFilename);
Packit d14fb6
      rc = IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
   
Packit d14fb6
   if ( rc == IME_SUCCESS )
Packit d14fb6
   {
Packit d14fb6
      /* Get the raw data in file */
Packit d14fb6
      fseek(pImageFile, 0, SEEK_END);
Packit d14fb6
      pImageCtx->size  = ftell(pImageFile); 
Packit d14fb6
      if (pImageCtx->size <= 0) {
Packit d14fb6
         if (pImageCtx->size < 0)
Packit d14fb6
            lprintf(LOG_ERR, "Error seeking %s. %s\n", imageFilename, strerror(errno));
Packit d14fb6
         rc = IME_ERROR;
Packit d14fb6
         fclose(pImageFile);
Packit d14fb6
         return rc;
Packit d14fb6
      }
Packit d14fb6
      pImageCtx->pData = malloc(sizeof(unsigned char)*pImageCtx->size);
Packit d14fb6
      rewind(pImageFile);
Packit d14fb6
Packit d14fb6
      if ( pImageCtx->pData != NULL )
Packit d14fb6
      {
Packit d14fb6
         if (pImageCtx->size < fread(pImageCtx->pData, sizeof(unsigned char), 
Packit d14fb6
                                                   pImageCtx->size, pImageFile))
Packit d14fb6
            rc = IME_ERROR;
Packit d14fb6
      }
Packit d14fb6
      else
Packit d14fb6
      {
Packit d14fb6
         rc = IME_ERROR;
Packit d14fb6
      }
Packit d14fb6
   }
Packit d14fb6
   
Packit d14fb6
   // Calculate checksum CRC8  
Packit d14fb6
   if ( rc == IME_SUCCESS )
Packit d14fb6
   {
Packit d14fb6
      pImageCtx->crc8 = ImeCrc8(pImageCtx->size, pImageCtx->pData);
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
    
Packit d14fb6
   if( pImageFile != NULL)
Packit d14fb6
   {
Packit d14fb6
      fclose(pImageFile);
Packit d14fb6
   }
Packit d14fb6
    
Packit d14fb6
   return rc;
Packit d14fb6
}  
Packit d14fb6
Packit d14fb6
static uint8_t ImeCrc8( uint32_t length, uint8_t * pBuf )
Packit d14fb6
{
Packit d14fb6
   uint8_t crc = 0;
Packit d14fb6
   uint32_t bufCount;
Packit d14fb6
Packit d14fb6
   for ( bufCount = 0; bufCount < length; bufCount++ )
Packit d14fb6
   {
Packit d14fb6
      uint8_t count;
Packit d14fb6
Packit d14fb6
      crc = crc ^ pBuf[bufCount];
Packit d14fb6
  
Packit d14fb6
      for ( count = 0; count < 8; count++ ) 
Packit d14fb6
      {
Packit d14fb6
         if (( crc & 0x80 ) != 0 )
Packit d14fb6
         {
Packit d14fb6
            crc <<= 1;
Packit d14fb6
            crc ^= 0x07;
Packit d14fb6
         }
Packit d14fb6
         else
Packit d14fb6
         {
Packit d14fb6
            crc <<= 1;
Packit d14fb6
         }
Packit d14fb6
      }
Packit d14fb6
   }
Packit d14fb6
Packit d14fb6
   lprintf(LOG_DEBUG,"CRC8: %02xh\n", crc);
Packit d14fb6
   return crc;
Packit d14fb6
} 
Packit d14fb6
Packit d14fb6
Packit d14fb6
static int ImeManualRollback(struct ipmi_intf *intf)
Packit d14fb6
{
Packit d14fb6
   int rc = IME_SUCCESS;
Packit d14fb6
   tImeStatus imeStatus;
Packit d14fb6
Packit d14fb6
   rc = ImeUpdateRegisterUpdate(intf, IME_UPDTYPE_MANUAL_ROLLBACK);
Packit d14fb6
   ImeUpdateGetStatus(intf,&imeStatus);
Packit d14fb6
Packit d14fb6
Packit d14fb6
   if(
Packit d14fb6
      (rc == IME_SUCCESS) &&
Packit d14fb6
      (imeStatus.update_state == IME_STATE_ROLLED_BACK) 
Packit d14fb6
     )
Packit d14fb6
   {
Packit d14fb6
      printf("Manual Rollback Succeed\n");
Packit d14fb6
      return IME_SUCCESS;
Packit d14fb6
   }
Packit d14fb6
   else
Packit d14fb6
   {
Packit d14fb6
      printf("Manual Rollback Completed With Error\n");
Packit d14fb6
      return IME_ERROR;
Packit d14fb6
   }
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
Packit d14fb6
static void ImePrintUsage(void)
Packit d14fb6
{
Packit d14fb6
   lprintf(LOG_NOTICE,"help                    - This help menu");   
Packit d14fb6
   lprintf(LOG_NOTICE,"info                    - Information about the present Intel ME");   
Packit d14fb6
   lprintf(LOG_NOTICE,"update <file>           - Upgrade the ME firmware from received image <file>");
Packit d14fb6
   lprintf(LOG_NOTICE,"rollback                - Manual Rollback ME");
Packit d14fb6
//   lprintf(LOG_NOTICE,"rollback                - Rollback ME Firmware");
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
Packit d14fb6
int ipmi_ime_main(struct ipmi_intf * intf, int argc, char ** argv)
Packit d14fb6
{
Packit d14fb6
   int rc = IME_SUCCESS;
Packit d14fb6
   
Packit d14fb6
   lprintf(LOG_DEBUG,"ipmi_ime_main()");
Packit d14fb6
   
Packit d14fb6
Packit d14fb6
   if ( (argc == 0) || (strcmp(argv[0], "help") == 0) ) 
Packit d14fb6
   {
Packit d14fb6
      ImePrintUsage();
Packit d14fb6
   }
Packit d14fb6
   else if ( (argc == 0) || (strcmp(argv[0], "info") == 0) ) 
Packit d14fb6
   {
Packit d14fb6
      rc = ImeGetInfo(intf);
Packit d14fb6
   }
Packit d14fb6
   else if ( strcmp(argv[0], "update") == 0) 
Packit d14fb6
   {
Packit d14fb6
      if(argc == 2)
Packit d14fb6
      {
Packit d14fb6
         lprintf(LOG_NOTICE,"Update using file: %s", argv[1]);
Packit d14fb6
         rc = ImeUpgrade(intf, argv[1]);
Packit d14fb6
      }
Packit d14fb6
      else
Packit d14fb6
      {
Packit d14fb6
         lprintf(LOG_ERROR,"File must be provided with this option, see help\n");
Packit d14fb6
         rc = IME_ERROR;
Packit d14fb6
      }
Packit d14fb6
   }
Packit d14fb6
   else if ( (argc == 0) || (strcmp(argv[0], "rollback") == 0) ) 
Packit d14fb6
   {
Packit d14fb6
      rc = ImeManualRollback(intf);
Packit d14fb6
   }
Packit d14fb6
   else
Packit d14fb6
   {
Packit d14fb6
      ImePrintUsage(); 
Packit d14fb6
   }
Packit d14fb6
   
Packit d14fb6
   return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6