1*c18ec02fSPetter Reinholdtsen /*
2*c18ec02fSPetter Reinholdtsen * Copyright (c) 2007 Kontron Canada, Inc. All Rights Reserved.
3*c18ec02fSPetter Reinholdtsen *
4*c18ec02fSPetter Reinholdtsen * Base on code from
5*c18ec02fSPetter Reinholdtsen * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
6*c18ec02fSPetter Reinholdtsen *
7*c18ec02fSPetter Reinholdtsen * Redistribution and use in source and binary forms, with or without
8*c18ec02fSPetter Reinholdtsen * modification, are permitted provided that the following conditions
9*c18ec02fSPetter Reinholdtsen * are met:
10*c18ec02fSPetter Reinholdtsen *
11*c18ec02fSPetter Reinholdtsen * Redistribution of source code must retain the above copyright
12*c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer.
13*c18ec02fSPetter Reinholdtsen *
14*c18ec02fSPetter Reinholdtsen * Redistribution in binary form must reproduce the above copyright
15*c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer in the
16*c18ec02fSPetter Reinholdtsen * documentation and/or other materials provided with the distribution.
17*c18ec02fSPetter Reinholdtsen *
18*c18ec02fSPetter Reinholdtsen * Neither the name of Sun Microsystems, Inc. or the names of
19*c18ec02fSPetter Reinholdtsen * contributors may be used to endorse or promote products derived
20*c18ec02fSPetter Reinholdtsen * from this software without specific prior written permission.
21*c18ec02fSPetter Reinholdtsen *
22*c18ec02fSPetter Reinholdtsen * This software is provided "AS IS," without a warranty of any kind.
23*c18ec02fSPetter Reinholdtsen * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
24*c18ec02fSPetter Reinholdtsen * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
25*c18ec02fSPetter Reinholdtsen * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
26*c18ec02fSPetter Reinholdtsen * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
27*c18ec02fSPetter Reinholdtsen * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
28*c18ec02fSPetter Reinholdtsen * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
29*c18ec02fSPetter Reinholdtsen * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
30*c18ec02fSPetter Reinholdtsen * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
31*c18ec02fSPetter Reinholdtsen * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
32*c18ec02fSPetter Reinholdtsen * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
33*c18ec02fSPetter Reinholdtsen * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
34*c18ec02fSPetter Reinholdtsen */
35*c18ec02fSPetter Reinholdtsen
36*c18ec02fSPetter Reinholdtsen /****************************************************************************
37*c18ec02fSPetter Reinholdtsen *
38*c18ec02fSPetter Reinholdtsen * Copyright (c) 2009 Kontron Canada, Inc. All Rights Reserved.
39*c18ec02fSPetter Reinholdtsen *
40*c18ec02fSPetter Reinholdtsen * IME
41*c18ec02fSPetter Reinholdtsen * Intel Manageability Engine
42*c18ec02fSPetter Reinholdtsen * Firmware Update Agent
43*c18ec02fSPetter Reinholdtsen *
44*c18ec02fSPetter Reinholdtsen * The ME is an IPMI-enabled component included in Intel(R) Next Generation
45*c18ec02fSPetter Reinholdtsen * Server Chipset Nehalem-EP platforms.
46*c18ec02fSPetter Reinholdtsen *
47*c18ec02fSPetter Reinholdtsen * These are a few synonyms for the ME :
48*c18ec02fSPetter Reinholdtsen *
49*c18ec02fSPetter Reinholdtsen * - Dynamic Power Node Manager
50*c18ec02fSPetter Reinholdtsen * - Intelligent Power Node Manager
51*c18ec02fSPetter Reinholdtsen *
52*c18ec02fSPetter Reinholdtsen * Consult Intel litterature for more information on this technology.
53*c18ec02fSPetter Reinholdtsen *
54*c18ec02fSPetter Reinholdtsen * The ME firmware resides on the platform boot flash and contains read only
55*c18ec02fSPetter Reinholdtsen * boot code for the ME as well as boot image redundancy support.
56*c18ec02fSPetter Reinholdtsen *
57*c18ec02fSPetter Reinholdtsen * This module implements an Upgrade Agent for the ME firwmare. Because the ME
58*c18ec02fSPetter Reinholdtsen * implements IPMI command handling, the agent speaks directly to the ME. In other
59*c18ec02fSPetter Reinholdtsen * words, in order the reach the ME, the BMC must implement IPMB bridging.
60*c18ec02fSPetter Reinholdtsen *
61*c18ec02fSPetter Reinholdtsen * The update is done through IPMI (this is IPMITOOL right !), not HECI.
62*c18ec02fSPetter Reinholdtsen *
63*c18ec02fSPetter Reinholdtsen * Example: ME available at address 0x88 on IPMI channel 8:
64*c18ec02fSPetter Reinholdtsen * ipmitool -m 0x20 -t 0x88 -b 8 ime info
65*c18ec02fSPetter Reinholdtsen *
66*c18ec02fSPetter Reinholdtsen * !! WARNING - You MUST use an image provided by your board vendor. - WARNING !!
67*c18ec02fSPetter Reinholdtsen *
68*c18ec02fSPetter Reinholdtsen * author:
69*c18ec02fSPetter Reinholdtsen * Jean-Michel.Audet@ca.kontron.com
70*c18ec02fSPetter Reinholdtsen * Francois.Isabelle@ca.kontron.com
71*c18ec02fSPetter Reinholdtsen *
72*c18ec02fSPetter Reinholdtsen *****************************************************************************/
73*c18ec02fSPetter Reinholdtsen /*
74*c18ec02fSPetter Reinholdtsen * HISTORY
75*c18ec02fSPetter Reinholdtsen * ===========================================================================
76*c18ec02fSPetter Reinholdtsen * 2009-04-20
77*c18ec02fSPetter Reinholdtsen *
78*c18ec02fSPetter Reinholdtsen * First public release of Kontron
79*c18ec02fSPetter Reinholdtsen *
80*c18ec02fSPetter Reinholdtsen */
81*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_ime.h>
82*c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
83*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
84*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_mc.h>
85*c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
86*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_strings.h>
87*c18ec02fSPetter Reinholdtsen
88*c18ec02fSPetter Reinholdtsen
89*c18ec02fSPetter Reinholdtsen #undef OUTPUT_DEBUG
90*c18ec02fSPetter Reinholdtsen
91*c18ec02fSPetter Reinholdtsen #include <stdlib.h>
92*c18ec02fSPetter Reinholdtsen #include <string.h>
93*c18ec02fSPetter Reinholdtsen #include <errno.h>
94*c18ec02fSPetter Reinholdtsen #include <time.h>
95*c18ec02fSPetter Reinholdtsen
96*c18ec02fSPetter Reinholdtsen static const int IME_SUCCESS = 0;
97*c18ec02fSPetter Reinholdtsen static const int IME_ERROR = -1;
98*c18ec02fSPetter Reinholdtsen static const int IME_RESTART = -2;
99*c18ec02fSPetter Reinholdtsen
100*c18ec02fSPetter Reinholdtsen #define IME_UPGRADE_BUFFER_SIZE 22
101*c18ec02fSPetter Reinholdtsen #define IME_RETRY_COUNT 5
102*c18ec02fSPetter Reinholdtsen
103*c18ec02fSPetter Reinholdtsen typedef struct ImeUpdateImageCtx
104*c18ec02fSPetter Reinholdtsen {
105*c18ec02fSPetter Reinholdtsen uint32_t size;
106*c18ec02fSPetter Reinholdtsen uint8_t * pData;
107*c18ec02fSPetter Reinholdtsen uint8_t crc8;
108*c18ec02fSPetter Reinholdtsen }tImeUpdateImageCtx;
109*c18ec02fSPetter Reinholdtsen
110*c18ec02fSPetter Reinholdtsen typedef enum eImeState
111*c18ec02fSPetter Reinholdtsen {
112*c18ec02fSPetter Reinholdtsen IME_STATE_IDLE = 0,
113*c18ec02fSPetter Reinholdtsen IME_STATE_UPDATE_REQUESTED = 1,
114*c18ec02fSPetter Reinholdtsen IME_STATE_UPDATE_IN_PROGRESS = 2,
115*c18ec02fSPetter Reinholdtsen IME_STATE_SUCCESS = 3,
116*c18ec02fSPetter Reinholdtsen IME_STATE_FAILED = 4,
117*c18ec02fSPetter Reinholdtsen IME_STATE_ROLLED_BACK = 5,
118*c18ec02fSPetter Reinholdtsen IME_STATE_ABORTED = 6,
119*c18ec02fSPetter Reinholdtsen IME_STATE_INIT_FAILED = 7
120*c18ec02fSPetter Reinholdtsen } tImeStateEnum;
121*c18ec02fSPetter Reinholdtsen
122*c18ec02fSPetter Reinholdtsen
123*c18ec02fSPetter Reinholdtsen typedef enum tImeUpdateType
124*c18ec02fSPetter Reinholdtsen {
125*c18ec02fSPetter Reinholdtsen IME_UPDTYPE_NORMAL = 1,
126*c18ec02fSPetter Reinholdtsen IME_UPDTYPE_MANUAL_ROLLBACK = 3,
127*c18ec02fSPetter Reinholdtsen IME_UPDTYPE_ABORT = 4
128*c18ec02fSPetter Reinholdtsen } tImeUpdateType;
129*c18ec02fSPetter Reinholdtsen
130*c18ec02fSPetter Reinholdtsen
131*c18ec02fSPetter Reinholdtsen #ifdef HAVE_PRAGMA_PACK
132*c18ec02fSPetter Reinholdtsen #pragma pack(1)
133*c18ec02fSPetter Reinholdtsen #endif
134*c18ec02fSPetter Reinholdtsen typedef struct sImeStatus {
135*c18ec02fSPetter Reinholdtsen uint8_t image_status;
136*c18ec02fSPetter Reinholdtsen tImeStateEnum update_state;
137*c18ec02fSPetter Reinholdtsen uint8_t update_attempt_status;
138*c18ec02fSPetter Reinholdtsen uint8_t rollback_attempt_status;
139*c18ec02fSPetter Reinholdtsen uint8_t update_type;
140*c18ec02fSPetter Reinholdtsen uint8_t dependent_flag;
141*c18ec02fSPetter Reinholdtsen uint8_t free_area_size[4];
142*c18ec02fSPetter Reinholdtsen } ATTRIBUTE_PACKING tImeStatus ;
143*c18ec02fSPetter Reinholdtsen #ifdef HAVE_PRAGMA_PACK
144*c18ec02fSPetter Reinholdtsen #pragma pack(0)
145*c18ec02fSPetter Reinholdtsen #endif
146*c18ec02fSPetter Reinholdtsen
147*c18ec02fSPetter Reinholdtsen #ifdef HAVE_PRAGMA_PACK
148*c18ec02fSPetter Reinholdtsen #pragma pack(1)
149*c18ec02fSPetter Reinholdtsen #endif
150*c18ec02fSPetter Reinholdtsen typedef struct sImeCaps {
151*c18ec02fSPetter Reinholdtsen uint8_t area_supported;
152*c18ec02fSPetter Reinholdtsen uint8_t special_caps;
153*c18ec02fSPetter Reinholdtsen } ATTRIBUTE_PACKING tImeCaps ;
154*c18ec02fSPetter Reinholdtsen #ifdef HAVE_PRAGMA_PACK
155*c18ec02fSPetter Reinholdtsen #pragma pack(0)
156*c18ec02fSPetter Reinholdtsen #endif
157*c18ec02fSPetter Reinholdtsen
158*c18ec02fSPetter Reinholdtsen
159*c18ec02fSPetter Reinholdtsen static void ImePrintUsage(void);
160*c18ec02fSPetter Reinholdtsen static int ImeGetInfo(struct ipmi_intf *intf);
161*c18ec02fSPetter Reinholdtsen static int ImeUpgrade(struct ipmi_intf *intf, char* imageFilename);
162*c18ec02fSPetter Reinholdtsen static int ImeManualRollback(struct ipmi_intf *intf);
163*c18ec02fSPetter Reinholdtsen static int ImeUpdatePrepare(struct ipmi_intf *intf);
164*c18ec02fSPetter Reinholdtsen static int ImeUpdateOpenArea(struct ipmi_intf *intf);
165*c18ec02fSPetter Reinholdtsen static int ImeUpdateWriteArea(
166*c18ec02fSPetter Reinholdtsen struct ipmi_intf *intf,
167*c18ec02fSPetter Reinholdtsen uint8_t sequence,
168*c18ec02fSPetter Reinholdtsen uint8_t length,
169*c18ec02fSPetter Reinholdtsen uint8_t * pBuf
170*c18ec02fSPetter Reinholdtsen );
171*c18ec02fSPetter Reinholdtsen static int ImeUpdateCloseArea(
172*c18ec02fSPetter Reinholdtsen struct ipmi_intf *intf,
173*c18ec02fSPetter Reinholdtsen uint32_t size,
174*c18ec02fSPetter Reinholdtsen uint16_t checksum
175*c18ec02fSPetter Reinholdtsen );
176*c18ec02fSPetter Reinholdtsen
177*c18ec02fSPetter Reinholdtsen static int ImeUpdateGetStatus(struct ipmi_intf *intf, tImeStatus *pStatus);
178*c18ec02fSPetter Reinholdtsen static int ImeUpdateGetCapabilities(struct ipmi_intf *intf, tImeCaps *pCaps );
179*c18ec02fSPetter Reinholdtsen static int ImeUpdateRegisterUpdate(struct ipmi_intf *intf, tImeUpdateType type);
180*c18ec02fSPetter Reinholdtsen
181*c18ec02fSPetter Reinholdtsen static int ImeImageCtxFromFile(
182*c18ec02fSPetter Reinholdtsen char * imageFilename,
183*c18ec02fSPetter Reinholdtsen tImeUpdateImageCtx * pImageCtx);
184*c18ec02fSPetter Reinholdtsen static int ImeUpdateShowStatus(struct ipmi_intf *intf);
185*c18ec02fSPetter Reinholdtsen
186*c18ec02fSPetter Reinholdtsen static uint8_t ImeCrc8( uint32_t length, uint8_t * pBuf );
187*c18ec02fSPetter Reinholdtsen
188*c18ec02fSPetter Reinholdtsen
ImeGetInfo(struct ipmi_intf * intf)189*c18ec02fSPetter Reinholdtsen static int ImeGetInfo(struct ipmi_intf *intf)
190*c18ec02fSPetter Reinholdtsen {
191*c18ec02fSPetter Reinholdtsen int rc = IME_ERROR;
192*c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
193*c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
194*c18ec02fSPetter Reinholdtsen struct ipm_devid_rsp *devid;
195*c18ec02fSPetter Reinholdtsen const char *product=NULL;
196*c18ec02fSPetter Reinholdtsen tImeStatus status;
197*c18ec02fSPetter Reinholdtsen tImeCaps caps;
198*c18ec02fSPetter Reinholdtsen
199*c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
200*c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP;
201*c18ec02fSPetter Reinholdtsen req.msg.cmd = BMC_GET_DEVICE_ID;
202*c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
203*c18ec02fSPetter Reinholdtsen
204*c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
205*c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
206*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Device ID command failed");
207*c18ec02fSPetter Reinholdtsen return IME_ERROR;
208*c18ec02fSPetter Reinholdtsen }
209*c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
210*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Device ID command failed: %s",
211*c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
212*c18ec02fSPetter Reinholdtsen return IME_ERROR;
213*c18ec02fSPetter Reinholdtsen }
214*c18ec02fSPetter Reinholdtsen
215*c18ec02fSPetter Reinholdtsen devid = (struct ipm_devid_rsp *) rsp->data;
216*c18ec02fSPetter Reinholdtsen
217*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG,"Device ID : %i", devid->device_id);
218*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG,"Device Revision : %i",
219*c18ec02fSPetter Reinholdtsen devid->device_revision & IPM_DEV_DEVICE_ID_REV_MASK);
220*c18ec02fSPetter Reinholdtsen
221*c18ec02fSPetter Reinholdtsen if(
222*c18ec02fSPetter Reinholdtsen (devid->device_id == 0)
223*c18ec02fSPetter Reinholdtsen &&
224*c18ec02fSPetter Reinholdtsen ((devid->device_revision & IPM_DEV_DEVICE_ID_REV_MASK) == 0)
225*c18ec02fSPetter Reinholdtsen &&
226*c18ec02fSPetter Reinholdtsen (
227*c18ec02fSPetter Reinholdtsen (devid->manufacturer_id[0] == 0x57) // Intel
228*c18ec02fSPetter Reinholdtsen &&
229*c18ec02fSPetter Reinholdtsen (devid->manufacturer_id[1] == 0x01) // Intel
230*c18ec02fSPetter Reinholdtsen &&
231*c18ec02fSPetter Reinholdtsen (devid->manufacturer_id[2] == 0x00) // Intel
232*c18ec02fSPetter Reinholdtsen )
233*c18ec02fSPetter Reinholdtsen &&
234*c18ec02fSPetter Reinholdtsen (
235*c18ec02fSPetter Reinholdtsen (devid->product_id[1] == 0x0b)
236*c18ec02fSPetter Reinholdtsen &&
237*c18ec02fSPetter Reinholdtsen (devid->product_id[0] == 0x00)
238*c18ec02fSPetter Reinholdtsen )
239*c18ec02fSPetter Reinholdtsen )
240*c18ec02fSPetter Reinholdtsen {
241*c18ec02fSPetter Reinholdtsen rc = IME_SUCCESS;
242*c18ec02fSPetter Reinholdtsen printf("Manufacturer Name : %s\n",
243*c18ec02fSPetter Reinholdtsen val2str( (long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id),
244*c18ec02fSPetter Reinholdtsen ipmi_oem_info) );
245*c18ec02fSPetter Reinholdtsen
246*c18ec02fSPetter Reinholdtsen printf("Product ID : %u (0x%02x%02x)\n",
247*c18ec02fSPetter Reinholdtsen buf2short((uint8_t *)(devid->product_id)),
248*c18ec02fSPetter Reinholdtsen devid->product_id[1], devid->product_id[0]);
249*c18ec02fSPetter Reinholdtsen
250*c18ec02fSPetter Reinholdtsen product=oemval2str(IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id),
251*c18ec02fSPetter Reinholdtsen (devid->product_id[1]<<8)+devid->product_id[0],
252*c18ec02fSPetter Reinholdtsen ipmi_oem_product_info);
253*c18ec02fSPetter Reinholdtsen
254*c18ec02fSPetter Reinholdtsen if (product!=NULL)
255*c18ec02fSPetter Reinholdtsen {
256*c18ec02fSPetter Reinholdtsen printf("Product Name : %s\n", product);
257*c18ec02fSPetter Reinholdtsen }
258*c18ec02fSPetter Reinholdtsen
259*c18ec02fSPetter Reinholdtsen printf("Intel ME Firmware Revision : %x.%02x.%02x.%x%x%x.%x\n",
260*c18ec02fSPetter Reinholdtsen ((devid->fw_rev1 & IPM_DEV_FWREV1_MAJOR_MASK ) ),
261*c18ec02fSPetter Reinholdtsen ((devid->fw_rev2 ) >> 4),
262*c18ec02fSPetter Reinholdtsen ((devid->fw_rev2 ) & 0x0f),
263*c18ec02fSPetter Reinholdtsen ((devid->aux_fw_rev[1] ) >> 4),
264*c18ec02fSPetter Reinholdtsen ((devid->aux_fw_rev[1] ) & 0x0f),
265*c18ec02fSPetter Reinholdtsen ((devid->aux_fw_rev[2] ) >> 4),
266*c18ec02fSPetter Reinholdtsen ((devid->aux_fw_rev[2] ) & 0x0f)
267*c18ec02fSPetter Reinholdtsen );
268*c18ec02fSPetter Reinholdtsen
269*c18ec02fSPetter Reinholdtsen printf("SPS FW IPMI cmd version : %x.%x\n",
270*c18ec02fSPetter Reinholdtsen devid->aux_fw_rev[0] >> 4,
271*c18ec02fSPetter Reinholdtsen devid->aux_fw_rev[0] & 0x0f);
272*c18ec02fSPetter Reinholdtsen
273*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG,"Flags: %xh", devid->aux_fw_rev[3]);
274*c18ec02fSPetter Reinholdtsen
275*c18ec02fSPetter Reinholdtsen printf("Current Image Type : ");
276*c18ec02fSPetter Reinholdtsen switch( (devid->aux_fw_rev[3] & 0x03) )
277*c18ec02fSPetter Reinholdtsen {
278*c18ec02fSPetter Reinholdtsen case 0:
279*c18ec02fSPetter Reinholdtsen printf("Recovery\n");
280*c18ec02fSPetter Reinholdtsen break;
281*c18ec02fSPetter Reinholdtsen
282*c18ec02fSPetter Reinholdtsen case 1:
283*c18ec02fSPetter Reinholdtsen printf("Operational Image 1\n");
284*c18ec02fSPetter Reinholdtsen break;
285*c18ec02fSPetter Reinholdtsen
286*c18ec02fSPetter Reinholdtsen case 2:
287*c18ec02fSPetter Reinholdtsen printf("Operational Image 2\n");
288*c18ec02fSPetter Reinholdtsen break;
289*c18ec02fSPetter Reinholdtsen
290*c18ec02fSPetter Reinholdtsen case 3:
291*c18ec02fSPetter Reinholdtsen default:
292*c18ec02fSPetter Reinholdtsen printf("Unknown\n");
293*c18ec02fSPetter Reinholdtsen break;
294*c18ec02fSPetter Reinholdtsen }
295*c18ec02fSPetter Reinholdtsen }
296*c18ec02fSPetter Reinholdtsen else
297*c18ec02fSPetter Reinholdtsen {
298*c18ec02fSPetter Reinholdtsen printf("Supported ME not found\n");
299*c18ec02fSPetter Reinholdtsen }
300*c18ec02fSPetter Reinholdtsen
301*c18ec02fSPetter Reinholdtsen if(rc == IME_SUCCESS)
302*c18ec02fSPetter Reinholdtsen {
303*c18ec02fSPetter Reinholdtsen rc = ImeUpdateGetStatus(intf, &status);
304*c18ec02fSPetter Reinholdtsen
305*c18ec02fSPetter Reinholdtsen if(rc == IME_SUCCESS)
306*c18ec02fSPetter Reinholdtsen {
307*c18ec02fSPetter Reinholdtsen rc = ImeUpdateGetCapabilities(intf, &caps);
308*c18ec02fSPetter Reinholdtsen }
309*c18ec02fSPetter Reinholdtsen
310*c18ec02fSPetter Reinholdtsen }
311*c18ec02fSPetter Reinholdtsen
312*c18ec02fSPetter Reinholdtsen if(rc == IME_SUCCESS)
313*c18ec02fSPetter Reinholdtsen {
314*c18ec02fSPetter Reinholdtsen uint8_t newImage = ((status.image_status >> 1) & 0x01);
315*c18ec02fSPetter Reinholdtsen uint8_t rollImage = ((status.image_status >> 2) & 0x01);
316*c18ec02fSPetter Reinholdtsen uint8_t runArea = ((status.image_status >> 3) & 0x03);
317*c18ec02fSPetter Reinholdtsen uint8_t rollSup = ((caps.special_caps >> 0) & 0x01);
318*c18ec02fSPetter Reinholdtsen uint8_t recovSup = ((caps.special_caps >> 1) & 0x01);
319*c18ec02fSPetter Reinholdtsen
320*c18ec02fSPetter Reinholdtsen uint8_t operSup = ((caps.area_supported >> 1) & 0x01);
321*c18ec02fSPetter Reinholdtsen uint8_t piaSup = ((caps.area_supported >> 2) & 0x01);
322*c18ec02fSPetter Reinholdtsen uint8_t sdrSup = ((caps.area_supported >> 3) & 0x01);
323*c18ec02fSPetter Reinholdtsen
324*c18ec02fSPetter Reinholdtsen printf("\nSupported Area\n");
325*c18ec02fSPetter Reinholdtsen printf(" Operation Code : %s\n", (operSup ? "Supported" : "Unsupported"));
326*c18ec02fSPetter Reinholdtsen printf(" PIA : %s\n", (piaSup ? "Supported" : "Unsupported"));
327*c18ec02fSPetter Reinholdtsen printf(" SDR : %s\n", (sdrSup ? "Supported" : "Unsupported"));
328*c18ec02fSPetter Reinholdtsen
329*c18ec02fSPetter Reinholdtsen printf("\nSpecial Capabilities\n");
330*c18ec02fSPetter Reinholdtsen printf(" Rollback : %s\n", (rollSup ? "Supported" : "Unsupported"));
331*c18ec02fSPetter Reinholdtsen printf(" Recovery : %s\n", (recovSup ? "Supported" : "Unsupported"));
332*c18ec02fSPetter Reinholdtsen
333*c18ec02fSPetter Reinholdtsen printf("\nImage Status\n");
334*c18ec02fSPetter Reinholdtsen printf(" Staging (new) : %s\n", (newImage ? "Valid" : "Invalid"));
335*c18ec02fSPetter Reinholdtsen printf(" Rollback : %s\n", (rollImage ? "Valid" : "Invalid"));
336*c18ec02fSPetter Reinholdtsen if(runArea == 0)
337*c18ec02fSPetter Reinholdtsen printf(" Running Image Area : CODE\n");
338*c18ec02fSPetter Reinholdtsen else
339*c18ec02fSPetter Reinholdtsen printf(" Running Image Area : CODE%d\n", runArea);
340*c18ec02fSPetter Reinholdtsen
341*c18ec02fSPetter Reinholdtsen }
342*c18ec02fSPetter Reinholdtsen
343*c18ec02fSPetter Reinholdtsen return rc;
344*c18ec02fSPetter Reinholdtsen }
345*c18ec02fSPetter Reinholdtsen
346*c18ec02fSPetter Reinholdtsen
ImeUpgrade(struct ipmi_intf * intf,char * imageFilename)347*c18ec02fSPetter Reinholdtsen static int ImeUpgrade(struct ipmi_intf *intf, char* imageFilename)
348*c18ec02fSPetter Reinholdtsen {
349*c18ec02fSPetter Reinholdtsen int rc = IME_SUCCESS;
350*c18ec02fSPetter Reinholdtsen tImeUpdateImageCtx imgCtx;
351*c18ec02fSPetter Reinholdtsen tImeStatus imeStatus;
352*c18ec02fSPetter Reinholdtsen time_t start,end,current;
353*c18ec02fSPetter Reinholdtsen
354*c18ec02fSPetter Reinholdtsen time(&start);
355*c18ec02fSPetter Reinholdtsen
356*c18ec02fSPetter Reinholdtsen memset(&imgCtx, 0, sizeof(tImeUpdateImageCtx));
357*c18ec02fSPetter Reinholdtsen
358*c18ec02fSPetter Reinholdtsen rc = ImeImageCtxFromFile(imageFilename, &imgCtx);
359*c18ec02fSPetter Reinholdtsen
360*c18ec02fSPetter Reinholdtsen if(
361*c18ec02fSPetter Reinholdtsen (rc == IME_ERROR) ||
362*c18ec02fSPetter Reinholdtsen (imgCtx.pData == NULL) ||
363*c18ec02fSPetter Reinholdtsen (imgCtx.size == 0)
364*c18ec02fSPetter Reinholdtsen )
365*c18ec02fSPetter Reinholdtsen {
366*c18ec02fSPetter Reinholdtsen return IME_ERROR;
367*c18ec02fSPetter Reinholdtsen }
368*c18ec02fSPetter Reinholdtsen
369*c18ec02fSPetter Reinholdtsen ImeUpdateGetStatus(intf,&imeStatus);
370*c18ec02fSPetter Reinholdtsen
371*c18ec02fSPetter Reinholdtsen if(rc == IME_SUCCESS)
372*c18ec02fSPetter Reinholdtsen {
373*c18ec02fSPetter Reinholdtsen rc = ImeUpdatePrepare(intf);
374*c18ec02fSPetter Reinholdtsen ImeUpdateGetStatus(intf,&imeStatus);
375*c18ec02fSPetter Reinholdtsen }
376*c18ec02fSPetter Reinholdtsen
377*c18ec02fSPetter Reinholdtsen if(
378*c18ec02fSPetter Reinholdtsen (rc == IME_SUCCESS) &&
379*c18ec02fSPetter Reinholdtsen (imeStatus.update_state == IME_STATE_UPDATE_REQUESTED)
380*c18ec02fSPetter Reinholdtsen )
381*c18ec02fSPetter Reinholdtsen {
382*c18ec02fSPetter Reinholdtsen rc = ImeUpdateOpenArea(intf);
383*c18ec02fSPetter Reinholdtsen ImeUpdateGetStatus(intf,&imeStatus);
384*c18ec02fSPetter Reinholdtsen }
385*c18ec02fSPetter Reinholdtsen else if(rc == IME_SUCCESS)
386*c18ec02fSPetter Reinholdtsen {
387*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERROR,"ME state error (%i), aborting", imeStatus.update_state);
388*c18ec02fSPetter Reinholdtsen rc = IME_ERROR;
389*c18ec02fSPetter Reinholdtsen }
390*c18ec02fSPetter Reinholdtsen
391*c18ec02fSPetter Reinholdtsen
392*c18ec02fSPetter Reinholdtsen if(
393*c18ec02fSPetter Reinholdtsen (rc == IME_SUCCESS) &&
394*c18ec02fSPetter Reinholdtsen (imeStatus.update_state == IME_STATE_UPDATE_IN_PROGRESS)
395*c18ec02fSPetter Reinholdtsen )
396*c18ec02fSPetter Reinholdtsen {
397*c18ec02fSPetter Reinholdtsen uint8_t sequence = 0;
398*c18ec02fSPetter Reinholdtsen uint32_t counter = 0;
399*c18ec02fSPetter Reinholdtsen uint8_t retry = 0;
400*c18ec02fSPetter Reinholdtsen uint8_t shownPercent = 0xff;
401*c18ec02fSPetter Reinholdtsen
402*c18ec02fSPetter Reinholdtsen while(
403*c18ec02fSPetter Reinholdtsen (counter < imgCtx.size) &&
404*c18ec02fSPetter Reinholdtsen (rc == IME_SUCCESS) &&
405*c18ec02fSPetter Reinholdtsen (retry < IME_RETRY_COUNT)
406*c18ec02fSPetter Reinholdtsen )
407*c18ec02fSPetter Reinholdtsen {
408*c18ec02fSPetter Reinholdtsen uint8_t length = IME_UPGRADE_BUFFER_SIZE;
409*c18ec02fSPetter Reinholdtsen uint8_t currentPercent;
410*c18ec02fSPetter Reinholdtsen
411*c18ec02fSPetter Reinholdtsen if( (imgCtx.size - counter) < IME_UPGRADE_BUFFER_SIZE )
412*c18ec02fSPetter Reinholdtsen {
413*c18ec02fSPetter Reinholdtsen length = (imgCtx.size - counter);
414*c18ec02fSPetter Reinholdtsen }
415*c18ec02fSPetter Reinholdtsen
416*c18ec02fSPetter Reinholdtsen rc = ImeUpdateWriteArea(intf,sequence,length,&imgCtx.pData[counter]);
417*c18ec02fSPetter Reinholdtsen
418*c18ec02fSPetter Reinholdtsen /*
419*c18ec02fSPetter Reinholdtsen As per the flowchart Intel Dynamic Power Node Manager 1.5 IPMI Iface
420*c18ec02fSPetter Reinholdtsen page 65
421*c18ec02fSPetter Reinholdtsen We shall send the GetStatus command each time following a write area
422*c18ec02fSPetter Reinholdtsen but this add too much time to the upgrade
423*c18ec02fSPetter Reinholdtsen */
424*c18ec02fSPetter Reinholdtsen /* ImeUpdateGetStatus(intf,&imeStatus); */
425*c18ec02fSPetter Reinholdtsen counter += length;
426*c18ec02fSPetter Reinholdtsen sequence ++;
427*c18ec02fSPetter Reinholdtsen
428*c18ec02fSPetter Reinholdtsen
429*c18ec02fSPetter Reinholdtsen currentPercent = ((float)counter/imgCtx.size)*100;
430*c18ec02fSPetter Reinholdtsen
431*c18ec02fSPetter Reinholdtsen if(currentPercent != shownPercent)
432*c18ec02fSPetter Reinholdtsen {
433*c18ec02fSPetter Reinholdtsen uint16_t timeElapsedSecond;
434*c18ec02fSPetter Reinholdtsen shownPercent = currentPercent;
435*c18ec02fSPetter Reinholdtsen printf("Percent: %02i, ", shownPercent);
436*c18ec02fSPetter Reinholdtsen time(¤t);
437*c18ec02fSPetter Reinholdtsen timeElapsedSecond = (current-start) + ((current-start)%60);
438*c18ec02fSPetter Reinholdtsen printf("Elapsed time %02ld:%02ld\r",((current-start)/60), ((current-start)%60));
439*c18ec02fSPetter Reinholdtsen fflush(stdout);
440*c18ec02fSPetter Reinholdtsen
441*c18ec02fSPetter Reinholdtsen }
442*c18ec02fSPetter Reinholdtsen }
443*c18ec02fSPetter Reinholdtsen ImeUpdateGetStatus(intf,&imeStatus);
444*c18ec02fSPetter Reinholdtsen printf("\n");
445*c18ec02fSPetter Reinholdtsen }
446*c18ec02fSPetter Reinholdtsen else if(rc == IME_SUCCESS)
447*c18ec02fSPetter Reinholdtsen {
448*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERROR,"ME state error (%i), aborting", imeStatus.update_state);
449*c18ec02fSPetter Reinholdtsen rc = IME_ERROR;
450*c18ec02fSPetter Reinholdtsen }
451*c18ec02fSPetter Reinholdtsen
452*c18ec02fSPetter Reinholdtsen if(
453*c18ec02fSPetter Reinholdtsen (rc == IME_SUCCESS) &&
454*c18ec02fSPetter Reinholdtsen (imeStatus.update_state == IME_STATE_UPDATE_IN_PROGRESS)
455*c18ec02fSPetter Reinholdtsen )
456*c18ec02fSPetter Reinholdtsen {
457*c18ec02fSPetter Reinholdtsen rc = ImeUpdateCloseArea(intf, imgCtx.size, imgCtx.crc8);
458*c18ec02fSPetter Reinholdtsen ImeUpdateGetStatus(intf,&imeStatus);
459*c18ec02fSPetter Reinholdtsen }
460*c18ec02fSPetter Reinholdtsen else if(rc == IME_SUCCESS)
461*c18ec02fSPetter Reinholdtsen {
462*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERROR,"ME state error, aborting");
463*c18ec02fSPetter Reinholdtsen rc = IME_ERROR;
464*c18ec02fSPetter Reinholdtsen }
465*c18ec02fSPetter Reinholdtsen
466*c18ec02fSPetter Reinholdtsen if(
467*c18ec02fSPetter Reinholdtsen (rc == IME_SUCCESS) &&
468*c18ec02fSPetter Reinholdtsen (imeStatus.update_state == IME_STATE_UPDATE_REQUESTED)
469*c18ec02fSPetter Reinholdtsen )
470*c18ec02fSPetter Reinholdtsen {
471*c18ec02fSPetter Reinholdtsen printf("UpdateCompleted, Activate now\n");
472*c18ec02fSPetter Reinholdtsen rc = ImeUpdateRegisterUpdate(intf, IME_UPDTYPE_NORMAL);
473*c18ec02fSPetter Reinholdtsen ImeUpdateGetStatus(intf,&imeStatus);
474*c18ec02fSPetter Reinholdtsen }
475*c18ec02fSPetter Reinholdtsen else if(rc == IME_SUCCESS)
476*c18ec02fSPetter Reinholdtsen {
477*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERROR,"ME state error, aborting");
478*c18ec02fSPetter Reinholdtsen rc = IME_ERROR;
479*c18ec02fSPetter Reinholdtsen }
480*c18ec02fSPetter Reinholdtsen
481*c18ec02fSPetter Reinholdtsen if(
482*c18ec02fSPetter Reinholdtsen (rc == IME_SUCCESS) &&
483*c18ec02fSPetter Reinholdtsen (imeStatus.update_state == IME_STATE_SUCCESS)
484*c18ec02fSPetter Reinholdtsen )
485*c18ec02fSPetter Reinholdtsen {
486*c18ec02fSPetter Reinholdtsen time(&end);
487*c18ec02fSPetter Reinholdtsen printf("Update Completed in %02ld:%02ld\n",(end-start)/60, (end-start)%60);
488*c18ec02fSPetter Reinholdtsen }
489*c18ec02fSPetter Reinholdtsen else
490*c18ec02fSPetter Reinholdtsen {
491*c18ec02fSPetter Reinholdtsen time(&end);
492*c18ec02fSPetter Reinholdtsen printf("Update Error\n");
493*c18ec02fSPetter Reinholdtsen printf("\nTime Taken %02ld:%02ld\n",(end-start)/60, (end-start)%60);
494*c18ec02fSPetter Reinholdtsen }
495*c18ec02fSPetter Reinholdtsen
496*c18ec02fSPetter Reinholdtsen return rc;
497*c18ec02fSPetter Reinholdtsen }
498*c18ec02fSPetter Reinholdtsen
499*c18ec02fSPetter Reinholdtsen
ImeUpdatePrepare(struct ipmi_intf * intf)500*c18ec02fSPetter Reinholdtsen static int ImeUpdatePrepare(struct ipmi_intf *intf)
501*c18ec02fSPetter Reinholdtsen {
502*c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
503*c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
504*c18ec02fSPetter Reinholdtsen
505*c18ec02fSPetter Reinholdtsen #ifdef OUTPUT_DEBUG
506*c18ec02fSPetter Reinholdtsen printf("ImeUpdatePrepare\n");
507*c18ec02fSPetter Reinholdtsen #endif
508*c18ec02fSPetter Reinholdtsen
509*c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
510*c18ec02fSPetter Reinholdtsen req.msg.netfn = 0x30; // OEM NetFn
511*c18ec02fSPetter Reinholdtsen req.msg.cmd = 0xA0;
512*c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
513*c18ec02fSPetter Reinholdtsen
514*c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
515*c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
516*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdatePrepare command failed");
517*c18ec02fSPetter Reinholdtsen return IME_ERROR;
518*c18ec02fSPetter Reinholdtsen }
519*c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
520*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdatePrepare command failed: %s",
521*c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
522*c18ec02fSPetter Reinholdtsen return IME_ERROR;
523*c18ec02fSPetter Reinholdtsen }
524*c18ec02fSPetter Reinholdtsen
525*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "UpdatePrepare command succeed");
526*c18ec02fSPetter Reinholdtsen return IME_SUCCESS;
527*c18ec02fSPetter Reinholdtsen }
528*c18ec02fSPetter Reinholdtsen
ImeUpdateOpenArea(struct ipmi_intf * intf)529*c18ec02fSPetter Reinholdtsen static int ImeUpdateOpenArea(struct ipmi_intf *intf)
530*c18ec02fSPetter Reinholdtsen {
531*c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
532*c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
533*c18ec02fSPetter Reinholdtsen uint8_t buffer[ 2 ];
534*c18ec02fSPetter Reinholdtsen
535*c18ec02fSPetter Reinholdtsen #ifdef OUTPUT_DEBUG
536*c18ec02fSPetter Reinholdtsen printf("ImeUpdateOpenArea\n");
537*c18ec02fSPetter Reinholdtsen #endif
538*c18ec02fSPetter Reinholdtsen
539*c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
540*c18ec02fSPetter Reinholdtsen req.msg.netfn = 0x30; // OEM NetFn
541*c18ec02fSPetter Reinholdtsen req.msg.cmd = 0xA1;
542*c18ec02fSPetter Reinholdtsen
543*c18ec02fSPetter Reinholdtsen buffer[0] = 0x01; // Area Type : Operational code
544*c18ec02fSPetter Reinholdtsen buffer[1] = 0x00; // Reserved : 0
545*c18ec02fSPetter Reinholdtsen req.msg.data = buffer;
546*c18ec02fSPetter Reinholdtsen
547*c18ec02fSPetter Reinholdtsen req.msg.data_len = 2;
548*c18ec02fSPetter Reinholdtsen
549*c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
550*c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
551*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdateOpenArea command failed");
552*c18ec02fSPetter Reinholdtsen return IME_ERROR;
553*c18ec02fSPetter Reinholdtsen }
554*c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
555*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdateOpenArea command failed: %s",
556*c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
557*c18ec02fSPetter Reinholdtsen return IME_ERROR;
558*c18ec02fSPetter Reinholdtsen }
559*c18ec02fSPetter Reinholdtsen
560*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "UpdateOpenArea command succeed");
561*c18ec02fSPetter Reinholdtsen return IME_SUCCESS;
562*c18ec02fSPetter Reinholdtsen }
563*c18ec02fSPetter Reinholdtsen
ImeUpdateWriteArea(struct ipmi_intf * intf,uint8_t sequence,uint8_t length,uint8_t * pBuf)564*c18ec02fSPetter Reinholdtsen static int ImeUpdateWriteArea(
565*c18ec02fSPetter Reinholdtsen struct ipmi_intf *intf,
566*c18ec02fSPetter Reinholdtsen uint8_t sequence,
567*c18ec02fSPetter Reinholdtsen uint8_t length,
568*c18ec02fSPetter Reinholdtsen uint8_t * pBuf
569*c18ec02fSPetter Reinholdtsen )
570*c18ec02fSPetter Reinholdtsen {
571*c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
572*c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
573*c18ec02fSPetter Reinholdtsen uint8_t buffer[ IME_UPGRADE_BUFFER_SIZE + 1 ];
574*c18ec02fSPetter Reinholdtsen
575*c18ec02fSPetter Reinholdtsen // printf("ImeUpdateWriteArea %i\n", sequence);
576*c18ec02fSPetter Reinholdtsen
577*c18ec02fSPetter Reinholdtsen if(length > IME_UPGRADE_BUFFER_SIZE)
578*c18ec02fSPetter Reinholdtsen return IME_ERROR;
579*c18ec02fSPetter Reinholdtsen
580*c18ec02fSPetter Reinholdtsen buffer[0] = sequence;
581*c18ec02fSPetter Reinholdtsen memcpy(&buffer[1], pBuf, length);
582*c18ec02fSPetter Reinholdtsen
583*c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
584*c18ec02fSPetter Reinholdtsen req.msg.netfn = 0x30; // OEM NetFn
585*c18ec02fSPetter Reinholdtsen req.msg.cmd = 0xA2;
586*c18ec02fSPetter Reinholdtsen req.msg.data = buffer;
587*c18ec02fSPetter Reinholdtsen req.msg.data_len = length + 1;
588*c18ec02fSPetter Reinholdtsen
589*c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
590*c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
591*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdateWriteArea command failed");
592*c18ec02fSPetter Reinholdtsen return IME_ERROR;
593*c18ec02fSPetter Reinholdtsen }
594*c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
595*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdateWriteArea command failed: %s",
596*c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
597*c18ec02fSPetter Reinholdtsen if( rsp->ccode == 0x80) // restart operation
598*c18ec02fSPetter Reinholdtsen return IME_RESTART;
599*c18ec02fSPetter Reinholdtsen else
600*c18ec02fSPetter Reinholdtsen return IME_ERROR;
601*c18ec02fSPetter Reinholdtsen }
602*c18ec02fSPetter Reinholdtsen
603*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "UpdateWriteArea command succeed");
604*c18ec02fSPetter Reinholdtsen return IME_SUCCESS;
605*c18ec02fSPetter Reinholdtsen }
606*c18ec02fSPetter Reinholdtsen
ImeUpdateCloseArea(struct ipmi_intf * intf,uint32_t size,uint16_t checksum)607*c18ec02fSPetter Reinholdtsen static int ImeUpdateCloseArea(
608*c18ec02fSPetter Reinholdtsen struct ipmi_intf *intf,
609*c18ec02fSPetter Reinholdtsen uint32_t size,
610*c18ec02fSPetter Reinholdtsen uint16_t checksum
611*c18ec02fSPetter Reinholdtsen )
612*c18ec02fSPetter Reinholdtsen {
613*c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
614*c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
615*c18ec02fSPetter Reinholdtsen uint8_t length = sizeof( uint32_t ) + sizeof( uint16_t );
616*c18ec02fSPetter Reinholdtsen uint8_t buffer[ sizeof( uint32_t ) + sizeof( uint16_t ) ];
617*c18ec02fSPetter Reinholdtsen
618*c18ec02fSPetter Reinholdtsen #ifdef OUTPUT_DEBUG
619*c18ec02fSPetter Reinholdtsen printf( "ImeUpdateCloseArea\n");
620*c18ec02fSPetter Reinholdtsen #endif
621*c18ec02fSPetter Reinholdtsen
622*c18ec02fSPetter Reinholdtsen buffer[0] = (uint8_t)((size & 0x000000ff) >> 0);
623*c18ec02fSPetter Reinholdtsen buffer[1] = (uint8_t)((size & 0x0000ff00) >> 8);
624*c18ec02fSPetter Reinholdtsen buffer[2] = (uint8_t)((size & 0x00ff0000) >> 16);
625*c18ec02fSPetter Reinholdtsen buffer[3] = (uint8_t)((size & 0xff000000) >> 24);
626*c18ec02fSPetter Reinholdtsen
627*c18ec02fSPetter Reinholdtsen buffer[4] = (uint8_t)((checksum & 0x00ff) >> 0);
628*c18ec02fSPetter Reinholdtsen buffer[5] = (uint8_t)((checksum & 0xff00) >> 8);
629*c18ec02fSPetter Reinholdtsen
630*c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
631*c18ec02fSPetter Reinholdtsen req.msg.netfn = 0x30; // OEM NetFn
632*c18ec02fSPetter Reinholdtsen req.msg.cmd = 0xA3;
633*c18ec02fSPetter Reinholdtsen req.msg.data = buffer;
634*c18ec02fSPetter Reinholdtsen req.msg.data_len = length;
635*c18ec02fSPetter Reinholdtsen
636*c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
637*c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
638*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdateCloseArea command failed");
639*c18ec02fSPetter Reinholdtsen return IME_ERROR;
640*c18ec02fSPetter Reinholdtsen }
641*c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
642*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdateCloseArea command failed: %s",
643*c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
644*c18ec02fSPetter Reinholdtsen return IME_ERROR;
645*c18ec02fSPetter Reinholdtsen }
646*c18ec02fSPetter Reinholdtsen
647*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "UpdateCloseArea command succeed");
648*c18ec02fSPetter Reinholdtsen return IME_SUCCESS;
649*c18ec02fSPetter Reinholdtsen }
650*c18ec02fSPetter Reinholdtsen
ImeUpdateGetStatus(struct ipmi_intf * intf,tImeStatus * pStatus)651*c18ec02fSPetter Reinholdtsen static int ImeUpdateGetStatus(struct ipmi_intf *intf, tImeStatus *pStatus )
652*c18ec02fSPetter Reinholdtsen {
653*c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
654*c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
655*c18ec02fSPetter Reinholdtsen tImeStatus *pGetStatus;
656*c18ec02fSPetter Reinholdtsen
657*c18ec02fSPetter Reinholdtsen memset(pStatus, 0, sizeof(tImeStatus));
658*c18ec02fSPetter Reinholdtsen pStatus->update_state = IME_STATE_ABORTED;
659*c18ec02fSPetter Reinholdtsen
660*c18ec02fSPetter Reinholdtsen
661*c18ec02fSPetter Reinholdtsen #ifdef OUTPUT_DEBUG
662*c18ec02fSPetter Reinholdtsen printf("ImeUpdateGetStatus: ");
663*c18ec02fSPetter Reinholdtsen #endif
664*c18ec02fSPetter Reinholdtsen
665*c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
666*c18ec02fSPetter Reinholdtsen req.msg.netfn = 0x30; // OEM NetFn
667*c18ec02fSPetter Reinholdtsen req.msg.cmd = 0xA6;
668*c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
669*c18ec02fSPetter Reinholdtsen
670*c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
671*c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
672*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdatePrepare command failed");
673*c18ec02fSPetter Reinholdtsen return IME_ERROR;
674*c18ec02fSPetter Reinholdtsen }
675*c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
676*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdatePrepare command failed: %s",
677*c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
678*c18ec02fSPetter Reinholdtsen return IME_ERROR;
679*c18ec02fSPetter Reinholdtsen }
680*c18ec02fSPetter Reinholdtsen
681*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "UpdatePrepare command succeed");
682*c18ec02fSPetter Reinholdtsen
683*c18ec02fSPetter Reinholdtsen pGetStatus = (tImeStatus *) rsp->data;
684*c18ec02fSPetter Reinholdtsen
685*c18ec02fSPetter Reinholdtsen memcpy( pStatus, pGetStatus, sizeof(tImeStatus));
686*c18ec02fSPetter Reinholdtsen
687*c18ec02fSPetter Reinholdtsen #ifdef OUTPUT_DEBUG
688*c18ec02fSPetter Reinholdtsen printf("%x - ", pStatus->updateState);
689*c18ec02fSPetter Reinholdtsen
690*c18ec02fSPetter Reinholdtsen switch( pStatus->update_state )
691*c18ec02fSPetter Reinholdtsen {
692*c18ec02fSPetter Reinholdtsen case IME_STATE_IDLE:
693*c18ec02fSPetter Reinholdtsen printf("IDLE\n");
694*c18ec02fSPetter Reinholdtsen break;
695*c18ec02fSPetter Reinholdtsen case IME_STATE_UPDATE_REQUESTED:
696*c18ec02fSPetter Reinholdtsen printf("Update Requested\n");
697*c18ec02fSPetter Reinholdtsen break;
698*c18ec02fSPetter Reinholdtsen case IME_STATE_UPDATE_IN_PROGRESS:
699*c18ec02fSPetter Reinholdtsen printf("Update in Progress\n");
700*c18ec02fSPetter Reinholdtsen break;
701*c18ec02fSPetter Reinholdtsen case IME_STATE_SUCCESS:
702*c18ec02fSPetter Reinholdtsen printf("Update Success\n");
703*c18ec02fSPetter Reinholdtsen break;
704*c18ec02fSPetter Reinholdtsen case IME_STATE_FAILED:
705*c18ec02fSPetter Reinholdtsen printf("Update Failed\n");
706*c18ec02fSPetter Reinholdtsen break;
707*c18ec02fSPetter Reinholdtsen case IME_STATE_ROLLED_BACK:
708*c18ec02fSPetter Reinholdtsen printf("Update Rolled Back\n");
709*c18ec02fSPetter Reinholdtsen break;
710*c18ec02fSPetter Reinholdtsen case IME_STATE_ABORTED:
711*c18ec02fSPetter Reinholdtsen printf("Update Aborted\n");
712*c18ec02fSPetter Reinholdtsen break;
713*c18ec02fSPetter Reinholdtsen case IME_STATE_INIT_FAILED:
714*c18ec02fSPetter Reinholdtsen printf("Update Init Failed\n");
715*c18ec02fSPetter Reinholdtsen break;
716*c18ec02fSPetter Reinholdtsen default:
717*c18ec02fSPetter Reinholdtsen printf("Unknown, reserved\n");
718*c18ec02fSPetter Reinholdtsen break;
719*c18ec02fSPetter Reinholdtsen }
720*c18ec02fSPetter Reinholdtsen #endif
721*c18ec02fSPetter Reinholdtsen
722*c18ec02fSPetter Reinholdtsen return IME_SUCCESS;
723*c18ec02fSPetter Reinholdtsen }
724*c18ec02fSPetter Reinholdtsen
ImeUpdateGetCapabilities(struct ipmi_intf * intf,tImeCaps * pCaps)725*c18ec02fSPetter Reinholdtsen static int ImeUpdateGetCapabilities(struct ipmi_intf *intf, tImeCaps *pCaps )
726*c18ec02fSPetter Reinholdtsen {
727*c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
728*c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
729*c18ec02fSPetter Reinholdtsen tImeCaps * pGetCaps;
730*c18ec02fSPetter Reinholdtsen
731*c18ec02fSPetter Reinholdtsen memset(pCaps, 0, sizeof(tImeCaps));
732*c18ec02fSPetter Reinholdtsen
733*c18ec02fSPetter Reinholdtsen
734*c18ec02fSPetter Reinholdtsen #ifdef OUTPUT_DEBUG
735*c18ec02fSPetter Reinholdtsen printf("ImeUpdateGetStatus: ");
736*c18ec02fSPetter Reinholdtsen #endif
737*c18ec02fSPetter Reinholdtsen
738*c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
739*c18ec02fSPetter Reinholdtsen req.msg.netfn = 0x30; // OEM NetFn
740*c18ec02fSPetter Reinholdtsen req.msg.cmd = 0xA7;
741*c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
742*c18ec02fSPetter Reinholdtsen
743*c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
744*c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
745*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdatePrepare command failed");
746*c18ec02fSPetter Reinholdtsen return IME_ERROR;
747*c18ec02fSPetter Reinholdtsen }
748*c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
749*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdatePrepare command failed: %s",
750*c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
751*c18ec02fSPetter Reinholdtsen return IME_ERROR;
752*c18ec02fSPetter Reinholdtsen }
753*c18ec02fSPetter Reinholdtsen
754*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "UpdatePrepare command succeed");
755*c18ec02fSPetter Reinholdtsen
756*c18ec02fSPetter Reinholdtsen pGetCaps = (tImeCaps *) rsp->data;
757*c18ec02fSPetter Reinholdtsen
758*c18ec02fSPetter Reinholdtsen memcpy( pCaps, pGetCaps, sizeof(tImeCaps));
759*c18ec02fSPetter Reinholdtsen
760*c18ec02fSPetter Reinholdtsen return IME_SUCCESS;
761*c18ec02fSPetter Reinholdtsen }
762*c18ec02fSPetter Reinholdtsen
763*c18ec02fSPetter Reinholdtsen
ImeUpdateRegisterUpdate(struct ipmi_intf * intf,tImeUpdateType type)764*c18ec02fSPetter Reinholdtsen static int ImeUpdateRegisterUpdate(struct ipmi_intf *intf, tImeUpdateType type)
765*c18ec02fSPetter Reinholdtsen {
766*c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
767*c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
768*c18ec02fSPetter Reinholdtsen uint8_t buffer[ 2 ];
769*c18ec02fSPetter Reinholdtsen
770*c18ec02fSPetter Reinholdtsen #ifdef OUTPUT_DEBUG
771*c18ec02fSPetter Reinholdtsen printf( "ImeUpdateRegisterUpdate\n");
772*c18ec02fSPetter Reinholdtsen #endif
773*c18ec02fSPetter Reinholdtsen
774*c18ec02fSPetter Reinholdtsen buffer[0] = type; // Normal Update
775*c18ec02fSPetter Reinholdtsen buffer[1] = 0; // Flags, reserved
776*c18ec02fSPetter Reinholdtsen
777*c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
778*c18ec02fSPetter Reinholdtsen req.msg.netfn = 0x30; // OEM NetFn
779*c18ec02fSPetter Reinholdtsen req.msg.cmd = 0xA4;
780*c18ec02fSPetter Reinholdtsen req.msg.data = buffer;
781*c18ec02fSPetter Reinholdtsen req.msg.data_len = 2;
782*c18ec02fSPetter Reinholdtsen
783*c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
784*c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
785*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ImeUpdateRegisterUpdate command failed");
786*c18ec02fSPetter Reinholdtsen return IME_ERROR;
787*c18ec02fSPetter Reinholdtsen }
788*c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
789*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ImeUpdateRegisterUpdate command failed: %s",
790*c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
791*c18ec02fSPetter Reinholdtsen return IME_ERROR;
792*c18ec02fSPetter Reinholdtsen }
793*c18ec02fSPetter Reinholdtsen
794*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "ImeUpdateRegisterUpdate command succeed");
795*c18ec02fSPetter Reinholdtsen return IME_SUCCESS;
796*c18ec02fSPetter Reinholdtsen }
797*c18ec02fSPetter Reinholdtsen
798*c18ec02fSPetter Reinholdtsen
799*c18ec02fSPetter Reinholdtsen
800*c18ec02fSPetter Reinholdtsen
ImeUpdateShowStatus(struct ipmi_intf * intf)801*c18ec02fSPetter Reinholdtsen static int ImeUpdateShowStatus(struct ipmi_intf *intf)
802*c18ec02fSPetter Reinholdtsen {
803*c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp;
804*c18ec02fSPetter Reinholdtsen struct ipmi_rq req;
805*c18ec02fSPetter Reinholdtsen tImeStatus *pStatus;
806*c18ec02fSPetter Reinholdtsen
807*c18ec02fSPetter Reinholdtsen printf("ImeUpdateGetStatus: ");
808*c18ec02fSPetter Reinholdtsen
809*c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req));
810*c18ec02fSPetter Reinholdtsen req.msg.netfn = 0x30; // OEM NetFn
811*c18ec02fSPetter Reinholdtsen req.msg.cmd = 0xA6;
812*c18ec02fSPetter Reinholdtsen req.msg.data_len = 0;
813*c18ec02fSPetter Reinholdtsen
814*c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req);
815*c18ec02fSPetter Reinholdtsen if (rsp == NULL) {
816*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdatePrepare command failed");
817*c18ec02fSPetter Reinholdtsen return IME_ERROR;
818*c18ec02fSPetter Reinholdtsen }
819*c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) {
820*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "UpdatePrepare command failed: %s",
821*c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals));
822*c18ec02fSPetter Reinholdtsen return IME_ERROR;
823*c18ec02fSPetter Reinholdtsen }
824*c18ec02fSPetter Reinholdtsen
825*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "UpdatePrepare command succeed");
826*c18ec02fSPetter Reinholdtsen
827*c18ec02fSPetter Reinholdtsen pStatus = (tImeStatus *) rsp->data ;
828*c18ec02fSPetter Reinholdtsen
829*c18ec02fSPetter Reinholdtsen
830*c18ec02fSPetter Reinholdtsen printf("image_status: %x - ", pStatus->image_status);
831*c18ec02fSPetter Reinholdtsen
832*c18ec02fSPetter Reinholdtsen printf("update_state: %x - ", pStatus->update_state);
833*c18ec02fSPetter Reinholdtsen
834*c18ec02fSPetter Reinholdtsen switch( pStatus->update_state )
835*c18ec02fSPetter Reinholdtsen {
836*c18ec02fSPetter Reinholdtsen case IME_STATE_IDLE:
837*c18ec02fSPetter Reinholdtsen printf("IDLE\n");
838*c18ec02fSPetter Reinholdtsen break;
839*c18ec02fSPetter Reinholdtsen case IME_STATE_UPDATE_REQUESTED:
840*c18ec02fSPetter Reinholdtsen printf("Update Requested\n");
841*c18ec02fSPetter Reinholdtsen break;
842*c18ec02fSPetter Reinholdtsen case IME_STATE_UPDATE_IN_PROGRESS:
843*c18ec02fSPetter Reinholdtsen printf("Update in Progress\n");
844*c18ec02fSPetter Reinholdtsen break;
845*c18ec02fSPetter Reinholdtsen case IME_STATE_SUCCESS:
846*c18ec02fSPetter Reinholdtsen printf("Update Success\n");
847*c18ec02fSPetter Reinholdtsen break;
848*c18ec02fSPetter Reinholdtsen case IME_STATE_FAILED:
849*c18ec02fSPetter Reinholdtsen printf("Update Failed\n");
850*c18ec02fSPetter Reinholdtsen break;
851*c18ec02fSPetter Reinholdtsen case IME_STATE_ROLLED_BACK:
852*c18ec02fSPetter Reinholdtsen printf("Update Rolled Back\n");
853*c18ec02fSPetter Reinholdtsen break;
854*c18ec02fSPetter Reinholdtsen case IME_STATE_ABORTED:
855*c18ec02fSPetter Reinholdtsen printf("Update Aborted\n");
856*c18ec02fSPetter Reinholdtsen break;
857*c18ec02fSPetter Reinholdtsen case IME_STATE_INIT_FAILED:
858*c18ec02fSPetter Reinholdtsen printf("Update Init Failed\n");
859*c18ec02fSPetter Reinholdtsen break;
860*c18ec02fSPetter Reinholdtsen default:
861*c18ec02fSPetter Reinholdtsen printf("Unknown, reserved\n");
862*c18ec02fSPetter Reinholdtsen break;
863*c18ec02fSPetter Reinholdtsen }
864*c18ec02fSPetter Reinholdtsen printf("update_attempt_status : %x\n", pStatus->update_attempt_status);
865*c18ec02fSPetter Reinholdtsen printf("rollback_attempt_status: %x\n", pStatus->rollback_attempt_status);
866*c18ec02fSPetter Reinholdtsen printf("update_type : %x\n", pStatus->update_type);
867*c18ec02fSPetter Reinholdtsen printf("dependent_flag : %x\n", pStatus->dependent_flag);
868*c18ec02fSPetter Reinholdtsen printf("free_area_size : %x\n", pStatus->free_area_size[0]);
869*c18ec02fSPetter Reinholdtsen printf(" : %x\n", pStatus->free_area_size[1]);
870*c18ec02fSPetter Reinholdtsen printf(" : %x\n", pStatus->free_area_size[2]);
871*c18ec02fSPetter Reinholdtsen printf(" : %x\n", pStatus->free_area_size[3]);
872*c18ec02fSPetter Reinholdtsen
873*c18ec02fSPetter Reinholdtsen return IME_SUCCESS;
874*c18ec02fSPetter Reinholdtsen }
875*c18ec02fSPetter Reinholdtsen
876*c18ec02fSPetter Reinholdtsen
ImeImageCtxFromFile(char * imageFilename,tImeUpdateImageCtx * pImageCtx)877*c18ec02fSPetter Reinholdtsen static int ImeImageCtxFromFile(
878*c18ec02fSPetter Reinholdtsen char* imageFilename,
879*c18ec02fSPetter Reinholdtsen tImeUpdateImageCtx * pImageCtx
880*c18ec02fSPetter Reinholdtsen )
881*c18ec02fSPetter Reinholdtsen {
882*c18ec02fSPetter Reinholdtsen int rc = IME_SUCCESS;
883*c18ec02fSPetter Reinholdtsen FILE* pImageFile = fopen(imageFilename, "rb");
884*c18ec02fSPetter Reinholdtsen
885*c18ec02fSPetter Reinholdtsen if ( pImageFile == NULL )
886*c18ec02fSPetter Reinholdtsen {
887*c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE,"Cannot open image file %s", imageFilename);
888*c18ec02fSPetter Reinholdtsen rc = IME_ERROR;
889*c18ec02fSPetter Reinholdtsen }
890*c18ec02fSPetter Reinholdtsen
891*c18ec02fSPetter Reinholdtsen if ( rc == IME_SUCCESS )
892*c18ec02fSPetter Reinholdtsen {
893*c18ec02fSPetter Reinholdtsen /* Get the raw data in file */
894*c18ec02fSPetter Reinholdtsen fseek(pImageFile, 0, SEEK_END);
895*c18ec02fSPetter Reinholdtsen pImageCtx->size = ftell(pImageFile);
896*c18ec02fSPetter Reinholdtsen if (pImageCtx->size <= 0) {
897*c18ec02fSPetter Reinholdtsen if (pImageCtx->size < 0)
898*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Error seeking %s. %s\n", imageFilename, strerror(errno));
899*c18ec02fSPetter Reinholdtsen rc = IME_ERROR;
900*c18ec02fSPetter Reinholdtsen fclose(pImageFile);
901*c18ec02fSPetter Reinholdtsen return rc;
902*c18ec02fSPetter Reinholdtsen }
903*c18ec02fSPetter Reinholdtsen pImageCtx->pData = malloc(sizeof(unsigned char)*pImageCtx->size);
904*c18ec02fSPetter Reinholdtsen rewind(pImageFile);
905*c18ec02fSPetter Reinholdtsen
906*c18ec02fSPetter Reinholdtsen if ( pImageCtx->pData != NULL )
907*c18ec02fSPetter Reinholdtsen {
908*c18ec02fSPetter Reinholdtsen if (pImageCtx->size < fread(pImageCtx->pData, sizeof(unsigned char),
909*c18ec02fSPetter Reinholdtsen pImageCtx->size, pImageFile))
910*c18ec02fSPetter Reinholdtsen rc = IME_ERROR;
911*c18ec02fSPetter Reinholdtsen }
912*c18ec02fSPetter Reinholdtsen else
913*c18ec02fSPetter Reinholdtsen {
914*c18ec02fSPetter Reinholdtsen rc = IME_ERROR;
915*c18ec02fSPetter Reinholdtsen }
916*c18ec02fSPetter Reinholdtsen }
917*c18ec02fSPetter Reinholdtsen
918*c18ec02fSPetter Reinholdtsen // Calculate checksum CRC8
919*c18ec02fSPetter Reinholdtsen if ( rc == IME_SUCCESS )
920*c18ec02fSPetter Reinholdtsen {
921*c18ec02fSPetter Reinholdtsen pImageCtx->crc8 = ImeCrc8(pImageCtx->size, pImageCtx->pData);
922*c18ec02fSPetter Reinholdtsen }
923*c18ec02fSPetter Reinholdtsen
924*c18ec02fSPetter Reinholdtsen
925*c18ec02fSPetter Reinholdtsen if( pImageFile != NULL)
926*c18ec02fSPetter Reinholdtsen {
927*c18ec02fSPetter Reinholdtsen fclose(pImageFile);
928*c18ec02fSPetter Reinholdtsen }
929*c18ec02fSPetter Reinholdtsen
930*c18ec02fSPetter Reinholdtsen return rc;
931*c18ec02fSPetter Reinholdtsen }
932*c18ec02fSPetter Reinholdtsen
ImeCrc8(uint32_t length,uint8_t * pBuf)933*c18ec02fSPetter Reinholdtsen static uint8_t ImeCrc8( uint32_t length, uint8_t * pBuf )
934*c18ec02fSPetter Reinholdtsen {
935*c18ec02fSPetter Reinholdtsen uint8_t crc = 0;
936*c18ec02fSPetter Reinholdtsen uint32_t bufCount;
937*c18ec02fSPetter Reinholdtsen
938*c18ec02fSPetter Reinholdtsen for ( bufCount = 0; bufCount < length; bufCount++ )
939*c18ec02fSPetter Reinholdtsen {
940*c18ec02fSPetter Reinholdtsen uint8_t count;
941*c18ec02fSPetter Reinholdtsen
942*c18ec02fSPetter Reinholdtsen crc = crc ^ pBuf[bufCount];
943*c18ec02fSPetter Reinholdtsen
944*c18ec02fSPetter Reinholdtsen for ( count = 0; count < 8; count++ )
945*c18ec02fSPetter Reinholdtsen {
946*c18ec02fSPetter Reinholdtsen if (( crc & 0x80 ) != 0 )
947*c18ec02fSPetter Reinholdtsen {
948*c18ec02fSPetter Reinholdtsen crc <<= 1;
949*c18ec02fSPetter Reinholdtsen crc ^= 0x07;
950*c18ec02fSPetter Reinholdtsen }
951*c18ec02fSPetter Reinholdtsen else
952*c18ec02fSPetter Reinholdtsen {
953*c18ec02fSPetter Reinholdtsen crc <<= 1;
954*c18ec02fSPetter Reinholdtsen }
955*c18ec02fSPetter Reinholdtsen }
956*c18ec02fSPetter Reinholdtsen }
957*c18ec02fSPetter Reinholdtsen
958*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG,"CRC8: %02xh\n", crc);
959*c18ec02fSPetter Reinholdtsen return crc;
960*c18ec02fSPetter Reinholdtsen }
961*c18ec02fSPetter Reinholdtsen
962*c18ec02fSPetter Reinholdtsen
ImeManualRollback(struct ipmi_intf * intf)963*c18ec02fSPetter Reinholdtsen static int ImeManualRollback(struct ipmi_intf *intf)
964*c18ec02fSPetter Reinholdtsen {
965*c18ec02fSPetter Reinholdtsen int rc = IME_SUCCESS;
966*c18ec02fSPetter Reinholdtsen tImeStatus imeStatus;
967*c18ec02fSPetter Reinholdtsen
968*c18ec02fSPetter Reinholdtsen rc = ImeUpdateRegisterUpdate(intf, IME_UPDTYPE_MANUAL_ROLLBACK);
969*c18ec02fSPetter Reinholdtsen ImeUpdateGetStatus(intf,&imeStatus);
970*c18ec02fSPetter Reinholdtsen
971*c18ec02fSPetter Reinholdtsen
972*c18ec02fSPetter Reinholdtsen if(
973*c18ec02fSPetter Reinholdtsen (rc == IME_SUCCESS) &&
974*c18ec02fSPetter Reinholdtsen (imeStatus.update_state == IME_STATE_ROLLED_BACK)
975*c18ec02fSPetter Reinholdtsen )
976*c18ec02fSPetter Reinholdtsen {
977*c18ec02fSPetter Reinholdtsen printf("Manual Rollback Succeed\n");
978*c18ec02fSPetter Reinholdtsen return IME_SUCCESS;
979*c18ec02fSPetter Reinholdtsen }
980*c18ec02fSPetter Reinholdtsen else
981*c18ec02fSPetter Reinholdtsen {
982*c18ec02fSPetter Reinholdtsen printf("Manual Rollback Completed With Error\n");
983*c18ec02fSPetter Reinholdtsen return IME_ERROR;
984*c18ec02fSPetter Reinholdtsen }
985*c18ec02fSPetter Reinholdtsen }
986*c18ec02fSPetter Reinholdtsen
987*c18ec02fSPetter Reinholdtsen
988*c18ec02fSPetter Reinholdtsen
ImePrintUsage(void)989*c18ec02fSPetter Reinholdtsen static void ImePrintUsage(void)
990*c18ec02fSPetter Reinholdtsen {
991*c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE,"help - This help menu");
992*c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE,"info - Information about the present Intel ME");
993*c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE,"update <file> - Upgrade the ME firmware from received image <file>");
994*c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE,"rollback - Manual Rollback ME");
995*c18ec02fSPetter Reinholdtsen // lprintf(LOG_NOTICE,"rollback - Rollback ME Firmware");
996*c18ec02fSPetter Reinholdtsen }
997*c18ec02fSPetter Reinholdtsen
998*c18ec02fSPetter Reinholdtsen
999*c18ec02fSPetter Reinholdtsen
ipmi_ime_main(struct ipmi_intf * intf,int argc,char ** argv)1000*c18ec02fSPetter Reinholdtsen int ipmi_ime_main(struct ipmi_intf * intf, int argc, char ** argv)
1001*c18ec02fSPetter Reinholdtsen {
1002*c18ec02fSPetter Reinholdtsen int rc = IME_SUCCESS;
1003*c18ec02fSPetter Reinholdtsen
1004*c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG,"ipmi_ime_main()");
1005*c18ec02fSPetter Reinholdtsen
1006*c18ec02fSPetter Reinholdtsen
1007*c18ec02fSPetter Reinholdtsen if ( (argc == 0) || (strcmp(argv[0], "help") == 0) )
1008*c18ec02fSPetter Reinholdtsen {
1009*c18ec02fSPetter Reinholdtsen ImePrintUsage();
1010*c18ec02fSPetter Reinholdtsen }
1011*c18ec02fSPetter Reinholdtsen else if ( (argc == 0) || (strcmp(argv[0], "info") == 0) )
1012*c18ec02fSPetter Reinholdtsen {
1013*c18ec02fSPetter Reinholdtsen rc = ImeGetInfo(intf);
1014*c18ec02fSPetter Reinholdtsen }
1015*c18ec02fSPetter Reinholdtsen else if ( strcmp(argv[0], "update") == 0)
1016*c18ec02fSPetter Reinholdtsen {
1017*c18ec02fSPetter Reinholdtsen if(argc == 2)
1018*c18ec02fSPetter Reinholdtsen {
1019*c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE,"Update using file: %s", argv[1]);
1020*c18ec02fSPetter Reinholdtsen rc = ImeUpgrade(intf, argv[1]);
1021*c18ec02fSPetter Reinholdtsen }
1022*c18ec02fSPetter Reinholdtsen else
1023*c18ec02fSPetter Reinholdtsen {
1024*c18ec02fSPetter Reinholdtsen lprintf(LOG_ERROR,"File must be provided with this option, see help\n");
1025*c18ec02fSPetter Reinholdtsen rc = IME_ERROR;
1026*c18ec02fSPetter Reinholdtsen }
1027*c18ec02fSPetter Reinholdtsen }
1028*c18ec02fSPetter Reinholdtsen else if ( (argc == 0) || (strcmp(argv[0], "rollback") == 0) )
1029*c18ec02fSPetter Reinholdtsen {
1030*c18ec02fSPetter Reinholdtsen rc = ImeManualRollback(intf);
1031*c18ec02fSPetter Reinholdtsen }
1032*c18ec02fSPetter Reinholdtsen else
1033*c18ec02fSPetter Reinholdtsen {
1034*c18ec02fSPetter Reinholdtsen ImePrintUsage();
1035*c18ec02fSPetter Reinholdtsen }
1036*c18ec02fSPetter Reinholdtsen
1037*c18ec02fSPetter Reinholdtsen return rc;
1038*c18ec02fSPetter Reinholdtsen }
1039*c18ec02fSPetter Reinholdtsen
1040*c18ec02fSPetter Reinholdtsen
1041*c18ec02fSPetter Reinholdtsen
1042