xref: /titanic_52/usr/src/cmd/fwflash/common/fwflash.h (revision 5a7763bf3e9db4cfe6cb523b096cb74af71e3793)
1*5a7763bfSjmcp /*
2*5a7763bfSjmcp  * CDDL HEADER START
3*5a7763bfSjmcp  *
4*5a7763bfSjmcp  * The contents of this file are subject to the terms of the
5*5a7763bfSjmcp  * Common Development and Distribution License (the "License").
6*5a7763bfSjmcp  * You may not use this file except in compliance with the License.
7*5a7763bfSjmcp  *
8*5a7763bfSjmcp  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5a7763bfSjmcp  * or http://www.opensolaris.org/os/licensing.
10*5a7763bfSjmcp  * See the License for the specific language governing permissions
11*5a7763bfSjmcp  * and limitations under the License.
12*5a7763bfSjmcp  *
13*5a7763bfSjmcp  * When distributing Covered Code, include this CDDL HEADER in each
14*5a7763bfSjmcp  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5a7763bfSjmcp  * If applicable, add the following below this CDDL HEADER, with the
16*5a7763bfSjmcp  * fields enclosed by brackets "[]" replaced with your own identifying
17*5a7763bfSjmcp  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5a7763bfSjmcp  *
19*5a7763bfSjmcp  * CDDL HEADER END
20*5a7763bfSjmcp  */
21*5a7763bfSjmcp /*
22*5a7763bfSjmcp  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*5a7763bfSjmcp  * Use is subject to license terms.
24*5a7763bfSjmcp  */
25*5a7763bfSjmcp 
26*5a7763bfSjmcp #ifndef	_FWFLASH_H
27*5a7763bfSjmcp #define	_FWFLASH_H
28*5a7763bfSjmcp 
29*5a7763bfSjmcp #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*5a7763bfSjmcp 
31*5a7763bfSjmcp /*
32*5a7763bfSjmcp  * fwflash.h
33*5a7763bfSjmcp  */
34*5a7763bfSjmcp 
35*5a7763bfSjmcp #ifdef __cplusplus
36*5a7763bfSjmcp extern "C" {
37*5a7763bfSjmcp #endif
38*5a7763bfSjmcp 
39*5a7763bfSjmcp #include <sys/queue.h>
40*5a7763bfSjmcp #include <libdevinfo.h>
41*5a7763bfSjmcp 
42*5a7763bfSjmcp 
43*5a7763bfSjmcp #define	MSG_INFO	0
44*5a7763bfSjmcp #define	MSG_WARN	1
45*5a7763bfSjmcp #define	MSG_ERROR	2
46*5a7763bfSjmcp int fwflash_debug;
47*5a7763bfSjmcp 
48*5a7763bfSjmcp #define	FWFLASH_SUCCESS		0
49*5a7763bfSjmcp #define	FWFLASH_FAILURE		1
50*5a7763bfSjmcp 
51*5a7763bfSjmcp #define	FWFLASH_FLASH_IMAGES	2
52*5a7763bfSjmcp 
53*5a7763bfSjmcp 
54*5a7763bfSjmcp #define	FWPLUGINDIR		"/usr/lib/fwflash/identify"
55*5a7763bfSjmcp #define	FWVERIFYPLUGINDIR	"/usr/lib/fwflash/verify"
56*5a7763bfSjmcp 
57*5a7763bfSjmcp /*
58*5a7763bfSjmcp  * we search for a variable (fwplugin_version, type uint32_t)
59*5a7763bfSjmcp  * which should equal FWPLUGIN_VERSION_1
60*5a7763bfSjmcp  */
61*5a7763bfSjmcp 
62*5a7763bfSjmcp #define	FWPLUGIN_VERSION_1	1
63*5a7763bfSjmcp 
64*5a7763bfSjmcp struct devicelist;
65*5a7763bfSjmcp 
66*5a7763bfSjmcp struct fw_plugin {
67*5a7763bfSjmcp 
68*5a7763bfSjmcp 	/*
69*5a7763bfSjmcp 	 * An opaque handle for dlopen()/dlclose() to use.
70*5a7763bfSjmcp 	 */
71*5a7763bfSjmcp 	void *handle;
72*5a7763bfSjmcp 
73*5a7763bfSjmcp 	/*
74*5a7763bfSjmcp 	 * fully-qualified filename in /usr/lib/fwflash/identify
75*5a7763bfSjmcp 	 * made up of [drivername].so
76*5a7763bfSjmcp 	 *
77*5a7763bfSjmcp 	 * eg  /usr/lib/fwflash/identify/ses.so
78*5a7763bfSjmcp 	 * is the identification plugin for devices attached to
79*5a7763bfSjmcp 	 * the host using the ses(7D) driver.
80*5a7763bfSjmcp 	 */
81*5a7763bfSjmcp 	char *filename;
82*5a7763bfSjmcp 
83*5a7763bfSjmcp 	/*
84*5a7763bfSjmcp 	 * The driver name that this plugin will search for in
85*5a7763bfSjmcp 	 * the device tree snapshot using di_drv_first_node(3DEVINFO)
86*5a7763bfSjmcp 	 * and di_drv_next_node(3DEVINFO).
87*5a7763bfSjmcp 	 */
88*5a7763bfSjmcp 	char *drvname; /* "ses" or "tavor" or .... */
89*5a7763bfSjmcp 
90*5a7763bfSjmcp 	/*
91*5a7763bfSjmcp 	 * Function entry point to support the command-line "-r"
92*5a7763bfSjmcp 	 * option - read image from device to persistent storage.
93*5a7763bfSjmcp 	 *
94*5a7763bfSjmcp 	 * Not all plugins and devices will support this operation.
95*5a7763bfSjmcp 	 */
96*5a7763bfSjmcp 	int (*fw_readfw)(struct devicelist *device, char *filename);
97*5a7763bfSjmcp 
98*5a7763bfSjmcp 
99*5a7763bfSjmcp 	/*
100*5a7763bfSjmcp 	 * Function entry point to support the command-line "-f"
101*5a7763bfSjmcp 	 * option - writes from persistent storage to device
102*5a7763bfSjmcp 	 *
103*5a7763bfSjmcp 	 * All identification plugins must support this operation.
104*5a7763bfSjmcp 	 */
105*5a7763bfSjmcp 	int (*fw_writefw)(struct devicelist *device, char *filename);
106*5a7763bfSjmcp 
107*5a7763bfSjmcp 
108*5a7763bfSjmcp 	/*
109*5a7763bfSjmcp 	 * Function entry point used to build the list of valid, flashable
110*5a7763bfSjmcp 	 * devices attached to the system using the loadable module drvname.
111*5a7763bfSjmcp 	 * (Not all devices attached using drvname will be valid for this
112*5a7763bfSjmcp 	 * plugin to report.
113*5a7763bfSjmcp 	 *
114*5a7763bfSjmcp 	 * start allows us to display flashable devices attached with
115*5a7763bfSjmcp 	 * different drivers and provide the user with a visual clue
116*5a7763bfSjmcp 	 * that these devices are different to others that are detected.
117*5a7763bfSjmcp 	 *
118*5a7763bfSjmcp 	 * All identification plugins must support this operation.
119*5a7763bfSjmcp 	 */
120*5a7763bfSjmcp 	int (*fw_identify)(int start);
121*5a7763bfSjmcp 
122*5a7763bfSjmcp 	/*
123*5a7763bfSjmcp 	 * Function entry point to support the command-line "-l"
124*5a7763bfSjmcp 	 * option - list/report flashable devices attached to the system.
125*5a7763bfSjmcp 	 *
126*5a7763bfSjmcp 	 * All identification plugins must support this operation.
127*5a7763bfSjmcp 	 */
128*5a7763bfSjmcp 	int (*fw_devinfo)(struct devicelist *thisdev);
129*5a7763bfSjmcp };
130*5a7763bfSjmcp 
131*5a7763bfSjmcp 
132*5a7763bfSjmcp struct pluginlist {
133*5a7763bfSjmcp 	/*
134*5a7763bfSjmcp 	 * fully qualified filename in /usr/lib/fwflash/identify
135*5a7763bfSjmcp 	 * made up of fwflash-[drivername].so
136*5a7763bfSjmcp 	 *
137*5a7763bfSjmcp 	 * eg  /usr/lib/fwflash/identify/ses.so
138*5a7763bfSjmcp 	 * is the identification plugin for devices attached to
139*5a7763bfSjmcp 	 * the host using the ses(7D) driver.
140*5a7763bfSjmcp 	 */
141*5a7763bfSjmcp 	char *filename;
142*5a7763bfSjmcp 
143*5a7763bfSjmcp 	/*
144*5a7763bfSjmcp 	 * The driver name that this plugin will search for in
145*5a7763bfSjmcp 	 * the device tree snapshot using di_drv_first_node(3DEVINFO)
146*5a7763bfSjmcp 	 * and di_drv_next_node(3DEVINFO).
147*5a7763bfSjmcp 	 */
148*5a7763bfSjmcp 	char *drvname;
149*5a7763bfSjmcp 
150*5a7763bfSjmcp 	/*
151*5a7763bfSjmcp 	 * pointer to the actual plugin, so we can access its
152*5a7763bfSjmcp 	 * function entry points
153*5a7763bfSjmcp 	 */
154*5a7763bfSjmcp 	struct fw_plugin *plugin;
155*5a7763bfSjmcp 
156*5a7763bfSjmcp 	/* pointer to the next element in the list */
157*5a7763bfSjmcp 	TAILQ_ENTRY(pluginlist) nextplugin;
158*5a7763bfSjmcp };
159*5a7763bfSjmcp 
160*5a7763bfSjmcp 
161*5a7763bfSjmcp struct vpr {
162*5a7763bfSjmcp 	/* vendor ID, eg "HITACHI " */
163*5a7763bfSjmcp 	char *vid;
164*5a7763bfSjmcp 
165*5a7763bfSjmcp 	/* product ID, eg "DK32EJ36NSUN36G " */
166*5a7763bfSjmcp 	char *pid;
167*5a7763bfSjmcp 
168*5a7763bfSjmcp 	/* revision, eg "PQ08" */
169*5a7763bfSjmcp 	char *revid;
170*5a7763bfSjmcp 
171*5a7763bfSjmcp 	/*
172*5a7763bfSjmcp 	 * Additional, encapsulated identifying information.
173*5a7763bfSjmcp 	 * This pointer allows us to add details such as the
174*5a7763bfSjmcp 	 * IB hba sector size, which command set should be
175*5a7763bfSjmcp 	 * used or a part number.
176*5a7763bfSjmcp 	 */
177*5a7763bfSjmcp 	void *encap_ident;
178*5a7763bfSjmcp };
179*5a7763bfSjmcp 
180*5a7763bfSjmcp 
181*5a7763bfSjmcp 
182*5a7763bfSjmcp 
183*5a7763bfSjmcp struct fwfile {
184*5a7763bfSjmcp 	/*
185*5a7763bfSjmcp 	 * The fully qualified filename. No default location for
186*5a7763bfSjmcp 	 * for the firmware image file is mandated.
187*5a7763bfSjmcp 	 */
188*5a7763bfSjmcp 	char *filename;
189*5a7763bfSjmcp 
190*5a7763bfSjmcp 	/* Pointer to the identification plugin required */
191*5a7763bfSjmcp 	struct fw_plugin *plugin;
192*5a7763bfSjmcp 
193*5a7763bfSjmcp 	/* pointer to the identification summary structure */
194*5a7763bfSjmcp 	struct vpr *ident;
195*5a7763bfSjmcp };
196*5a7763bfSjmcp 
197*5a7763bfSjmcp 
198*5a7763bfSjmcp 
199*5a7763bfSjmcp struct devicelist {
200*5a7763bfSjmcp 	/*
201*5a7763bfSjmcp 	 * fully qualified pathname, with /devices/.... prefix
202*5a7763bfSjmcp 	 */
203*5a7763bfSjmcp 	char *access_devname;
204*5a7763bfSjmcp 
205*5a7763bfSjmcp 	/*
206*5a7763bfSjmcp 	 * Which drivername did we find this device attached with
207*5a7763bfSjmcp 	 * in our device tree walk? Eg, ses or tavor or sgen...
208*5a7763bfSjmcp 	 */
209*5a7763bfSjmcp 	char *drvname;
210*5a7763bfSjmcp 
211*5a7763bfSjmcp 	/*
212*5a7763bfSjmcp 	 * What class of device is this? For tavor-attached devices,
213*5a7763bfSjmcp 	 * we set this to "IB". For other devices, unless there is
214*5a7763bfSjmcp 	 * a common name to use, just make this the same as the
215*5a7763bfSjmcp 	 * drvname field.
216*5a7763bfSjmcp 	 */
217*5a7763bfSjmcp 	char *classname;
218*5a7763bfSjmcp 
219*5a7763bfSjmcp 	/* pointer to the VPR structure */
220*5a7763bfSjmcp 	struct vpr *ident;
221*5a7763bfSjmcp 
222*5a7763bfSjmcp 	/*
223*5a7763bfSjmcp 	 * In the original fwflash(1M), it was possible to select a
224*5a7763bfSjmcp 	 * device for flashing by using an index number called a
225*5a7763bfSjmcp 	 * dev_num. We retain that concept for pluggable fwflash, with
226*5a7763bfSjmcp 	 * the following change - whenever our identification plugin has
227*5a7763bfSjmcp 	 * finished and found at least one acceptable device, we bump the
228*5a7763bfSjmcp 	 * index number by 100. This provides the user with another key
229*5a7763bfSjmcp 	 * to distinguish the desired device from a potentially very large
230*5a7763bfSjmcp 	 * list of similar-looking devices.
231*5a7763bfSjmcp 	 */
232*5a7763bfSjmcp 	unsigned int index;
233*5a7763bfSjmcp 
234*5a7763bfSjmcp 	/*
235*5a7763bfSjmcp 	 * Contains SAS or FC Port-WWNs, or IB GUIDS. Both SAS and FC only
236*5a7763bfSjmcp 	 * need one entry in this array since they really only have one
237*5a7763bfSjmcp 	 * address which we should track. IB devices can have 4 GUIDs
238*5a7763bfSjmcp 	 * (System Image, Node Image, Port 1 and Port 2).
239*5a7763bfSjmcp 	 */
240*5a7763bfSjmcp 	char *addresses[4];
241*5a7763bfSjmcp 
242*5a7763bfSjmcp 	/*
243*5a7763bfSjmcp 	 * Pointer to the plugin needed to flash this device, and
244*5a7763bfSjmcp 	 * to use for printing appropriate device-specific information
245*5a7763bfSjmcp 	 * as required by the "-l" option to fwflash(1M).
246*5a7763bfSjmcp 	 */
247*5a7763bfSjmcp 	struct fw_plugin *plugin;
248*5a7763bfSjmcp 
249*5a7763bfSjmcp 	/* Next entry in the list */
250*5a7763bfSjmcp 	TAILQ_ENTRY(devicelist) nextdev;
251*5a7763bfSjmcp };
252*5a7763bfSjmcp 
253*5a7763bfSjmcp 
254*5a7763bfSjmcp /*
255*5a7763bfSjmcp  * this type of plugin is for the firmware image vendor-specific
256*5a7763bfSjmcp  * verification functions, which we load from FWVERIFYPLUGINDIR
257*5a7763bfSjmcp  */
258*5a7763bfSjmcp 
259*5a7763bfSjmcp struct vrfyplugin {
260*5a7763bfSjmcp 
261*5a7763bfSjmcp 	/*
262*5a7763bfSjmcp 	 * fully-qualified filename in /usr/lib/fwflash/verify,
263*5a7763bfSjmcp 	 * made up of [drivername]-[vendorname].so
264*5a7763bfSjmcp 	 *
265*5a7763bfSjmcp 	 * eg  /usr/lib/fwflash/verify/ses-SUN.so
266*5a7763bfSjmcp 	 * is the verification plugin for ses-attached devices which
267*5a7763bfSjmcp 	 * have a vendorname of "SUN".
268*5a7763bfSjmcp 	 */
269*5a7763bfSjmcp 	char *filename;
270*5a7763bfSjmcp 
271*5a7763bfSjmcp 	/*
272*5a7763bfSjmcp 	 * The vendor name, such as "SUN" or "MELLANOX"
273*5a7763bfSjmcp 	 */
274*5a7763bfSjmcp 	char *vendor;
275*5a7763bfSjmcp 
276*5a7763bfSjmcp 	/*
277*5a7763bfSjmcp 	 * An opaque handle for dlopen()/dlclose() to use.
278*5a7763bfSjmcp 	 */
279*5a7763bfSjmcp 	void *handle;
280*5a7763bfSjmcp 
281*5a7763bfSjmcp 	/*
282*5a7763bfSjmcp 	 * Firmware image size in bytes, as reported by
283*5a7763bfSjmcp 	 * stat().
284*5a7763bfSjmcp 	 */
285*5a7763bfSjmcp 	unsigned int imgsize;
286*5a7763bfSjmcp 
287*5a7763bfSjmcp 	/*
288*5a7763bfSjmcp 	 * Flashable devices frequently have different buffers
289*5a7763bfSjmcp 	 * to use for different image types. We track the buffer
290*5a7763bfSjmcp 	 * required for this particular image with this variable.
291*5a7763bfSjmcp 	 *
292*5a7763bfSjmcp 	 * Once the verifier has figured out what sort of image
293*5a7763bfSjmcp 	 * it's been passed, it will know what value to use for
294*5a7763bfSjmcp 	 * this variable.
295*5a7763bfSjmcp 	 */
296*5a7763bfSjmcp 	unsigned int flashbuf;
297*5a7763bfSjmcp 
298*5a7763bfSjmcp 	/*
299*5a7763bfSjmcp 	 * Points to the entire firmware image in memory.
300*5a7763bfSjmcp 	 * We do this so we can avoid multiple open()/close()
301*5a7763bfSjmcp 	 * operations, and to make it easier for checksum
302*5a7763bfSjmcp 	 * calculations.
303*5a7763bfSjmcp 	 */
304*5a7763bfSjmcp 	int *fwimage;
305*5a7763bfSjmcp 
306*5a7763bfSjmcp 	/*
307*5a7763bfSjmcp 	 * We also store the name of the firmware file that
308*5a7763bfSjmcp 	 * we point to with *fwimage. This is needed in cases
309*5a7763bfSjmcp 	 * where we need to key off the name of the file to
310*5a7763bfSjmcp 	 * determine whether a different buffer in the target
311*5a7763bfSjmcp 	 * device should be targeted.
312*5a7763bfSjmcp 	 *
313*5a7763bfSjmcp 	 * For example, our "standard" firmware image (file.fw)
314*5a7763bfSjmcp 	 * might require use of buffer id 0, but a boot image
315*5a7763bfSjmcp 	 * (boot.fw) might require use of buffer id 17. In each
316*5a7763bfSjmcp 	 * case, it is the verifier plugin that determines the
317*5a7763bfSjmcp 	 * specific bufferid that is needed by that firmware image.
318*5a7763bfSjmcp 	 */
319*5a7763bfSjmcp 	char *imgfile;
320*5a7763bfSjmcp 
321*5a7763bfSjmcp 	/*
322*5a7763bfSjmcp 	 * The verification function entry point. The code
323*5a7763bfSjmcp 	 * in fwflash.c calls this function to verify that
324*5a7763bfSjmcp 	 * the nominated firmware image file is valid for
325*5a7763bfSjmcp 	 * the selected devicenode.
326*5a7763bfSjmcp 	 *
327*5a7763bfSjmcp 	 * Note that if the verification fails, the image
328*5a7763bfSjmcp 	 * does _not_ get force-flashed to the device.
329*5a7763bfSjmcp 	 */
330*5a7763bfSjmcp 	int (*vendorvrfy)(struct devicelist *devicenode);
331*5a7763bfSjmcp };
332*5a7763bfSjmcp 
333*5a7763bfSjmcp 
334*5a7763bfSjmcp 
335*5a7763bfSjmcp /* Flags for argument parsing */
336*5a7763bfSjmcp #define	FWFLASH_HELP_FLAG	0x01
337*5a7763bfSjmcp #define	FWFLASH_VER_FLAG	0x02
338*5a7763bfSjmcp #define	FWFLASH_YES_FLAG	0x04
339*5a7763bfSjmcp #define	FWFLASH_LIST_FLAG	0x08
340*5a7763bfSjmcp #define	FWFLASH_CLASS_FLAG	0x10
341*5a7763bfSjmcp #define	FWFLASH_DEVICE_FLAG	0x20
342*5a7763bfSjmcp #define	FWFLASH_FW_FLAG		0x40
343*5a7763bfSjmcp #define	FWFLASH_READ_FLAG	0x80
344*5a7763bfSjmcp 
345*5a7763bfSjmcp /* global variables for fwflash */
346*5a7763bfSjmcp 
347*5a7763bfSjmcp TAILQ_HEAD(PLUGINLIST, pluginlist);
348*5a7763bfSjmcp TAILQ_HEAD(DEVICELIST, devicelist);
349*5a7763bfSjmcp struct PLUGINLIST *fw_pluginlist;
350*5a7763bfSjmcp struct DEVICELIST *fw_devices;
351*5a7763bfSjmcp 
352*5a7763bfSjmcp 
353*5a7763bfSjmcp struct vrfyplugin *verifier;
354*5a7763bfSjmcp di_node_t rootnode;
355*5a7763bfSjmcp struct fw_plugin *self;
356*5a7763bfSjmcp 
357*5a7763bfSjmcp 
358*5a7763bfSjmcp /*
359*5a7763bfSjmcp  * utility defines and macros, since the firmware image we get
360*5a7763bfSjmcp  * from LSI is ARM-format and that means byte- and short-swapping
361*5a7763bfSjmcp  * on sparc
362*5a7763bfSjmcp  */
363*5a7763bfSjmcp 
364*5a7763bfSjmcp #define	HIGHBITS16		0xff00
365*5a7763bfSjmcp #define	HIGHBITS32		0xffff0000
366*5a7763bfSjmcp #define	HIGHBITS64		0xffffffff00000000ULL
367*5a7763bfSjmcp #define	LOWBITS16		0x00ff
368*5a7763bfSjmcp #define	LOWBITS32		0x0000ffff
369*5a7763bfSjmcp #define	LOWBITS64		0x00000000ffffffffULL
370*5a7763bfSjmcp 
371*5a7763bfSjmcp 
372*5a7763bfSjmcp #if defined(_LITTLE_ENDIAN)
373*5a7763bfSjmcp #define	ARMSWAPBITS(bs)	(bs)
374*5a7763bfSjmcp #define	MLXSWAPBITS16(bs)	\
375*5a7763bfSjmcp 	(BE_16(((bs) & LOWBITS16)) | BE_16(((bs) & HIGHBITS16)))
376*5a7763bfSjmcp #define	MLXSWAPBITS32(bs)	\
377*5a7763bfSjmcp 	(BE_32(((bs) & LOWBITS32)) | BE_32(((bs) & HIGHBITS32)))
378*5a7763bfSjmcp #define	MLXSWAPBITS64(bs)	\
379*5a7763bfSjmcp 	(BE_64(((bs) & LOWBITS64)) | BE_64(((bs) & HIGHBITS64)))
380*5a7763bfSjmcp #else
381*5a7763bfSjmcp #define	ARMSWAPBITS(bs)	(LE_32(((bs) & LOWBITS32)) | LE_32(((bs) & HIGHBITS32)))
382*5a7763bfSjmcp #define	MLXSWAPBITS16(bs)	(bs)
383*5a7763bfSjmcp #define	MLXSWAPBITS32(bs)	(bs)
384*5a7763bfSjmcp #define	MLXSWAPBITS64(bs)	(bs)
385*5a7763bfSjmcp 
386*5a7763bfSjmcp #endif
387*5a7763bfSjmcp 
388*5a7763bfSjmcp 
389*5a7763bfSjmcp /* common functions for fwflash */
390*5a7763bfSjmcp 
391*5a7763bfSjmcp void logmsg(int severity, char *msg, ...);
392*5a7763bfSjmcp 
393*5a7763bfSjmcp 
394*5a7763bfSjmcp #ifdef __cplusplus
395*5a7763bfSjmcp }
396*5a7763bfSjmcp #endif
397*5a7763bfSjmcp 
398*5a7763bfSjmcp #endif /* _FWFLASH_H */
399