xref: /titanic_51/usr/src/cmd/fwflash/common/fwflash.h (revision 87d06e46cdea545c3c673120b7211158dcfd35cc)
15a7763bfSjmcp /*
25a7763bfSjmcp  * CDDL HEADER START
35a7763bfSjmcp  *
45a7763bfSjmcp  * The contents of this file are subject to the terms of the
55a7763bfSjmcp  * Common Development and Distribution License (the "License").
65a7763bfSjmcp  * You may not use this file except in compliance with the License.
75a7763bfSjmcp  *
85a7763bfSjmcp  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95a7763bfSjmcp  * or http://www.opensolaris.org/os/licensing.
105a7763bfSjmcp  * See the License for the specific language governing permissions
115a7763bfSjmcp  * and limitations under the License.
125a7763bfSjmcp  *
135a7763bfSjmcp  * When distributing Covered Code, include this CDDL HEADER in each
145a7763bfSjmcp  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155a7763bfSjmcp  * If applicable, add the following below this CDDL HEADER, with the
165a7763bfSjmcp  * fields enclosed by brackets "[]" replaced with your own identifying
175a7763bfSjmcp  * information: Portions Copyright [yyyy] [name of copyright owner]
185a7763bfSjmcp  *
195a7763bfSjmcp  * CDDL HEADER END
205a7763bfSjmcp  */
215a7763bfSjmcp /*
22*87d06e46Speihong huang  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
235a7763bfSjmcp  * Use is subject to license terms.
245a7763bfSjmcp  */
255a7763bfSjmcp 
265a7763bfSjmcp #ifndef	_FWFLASH_H
275a7763bfSjmcp #define	_FWFLASH_H
285a7763bfSjmcp 
295a7763bfSjmcp /*
305a7763bfSjmcp  * fwflash.h
315a7763bfSjmcp  */
325a7763bfSjmcp 
335a7763bfSjmcp #ifdef __cplusplus
345a7763bfSjmcp extern "C" {
355a7763bfSjmcp #endif
365a7763bfSjmcp 
375a7763bfSjmcp #include <sys/queue.h>
385a7763bfSjmcp #include <libdevinfo.h>
395a7763bfSjmcp 
405a7763bfSjmcp 
415a7763bfSjmcp #define	MSG_INFO	0
425a7763bfSjmcp #define	MSG_WARN	1
435a7763bfSjmcp #define	MSG_ERROR	2
445a7763bfSjmcp int fwflash_debug;
455a7763bfSjmcp 
465a7763bfSjmcp #define	FWFLASH_SUCCESS		0
475a7763bfSjmcp #define	FWFLASH_FAILURE		1
485a7763bfSjmcp 
495a7763bfSjmcp #define	FWFLASH_FLASH_IMAGES	2
505a7763bfSjmcp 
515a7763bfSjmcp #define	FWPLUGINDIR		"/usr/lib/fwflash/identify"
525a7763bfSjmcp #define	FWVERIFYPLUGINDIR	"/usr/lib/fwflash/verify"
535a7763bfSjmcp 
545a7763bfSjmcp /*
555a7763bfSjmcp  * we search for a variable (fwplugin_version, type uint32_t)
565a7763bfSjmcp  * which should equal FWPLUGIN_VERSION_1
575a7763bfSjmcp  */
585a7763bfSjmcp 
595a7763bfSjmcp #define	FWPLUGIN_VERSION_1	1
605a7763bfSjmcp 
615a7763bfSjmcp struct devicelist;
625a7763bfSjmcp 
635a7763bfSjmcp struct fw_plugin {
645a7763bfSjmcp 	/*
655a7763bfSjmcp 	 * An opaque handle for dlopen()/dlclose() to use.
665a7763bfSjmcp 	 */
675a7763bfSjmcp 	void *handle;
685a7763bfSjmcp 
695a7763bfSjmcp 	/*
705a7763bfSjmcp 	 * fully-qualified filename in /usr/lib/fwflash/identify
715a7763bfSjmcp 	 * made up of [drivername].so
725a7763bfSjmcp 	 *
735a7763bfSjmcp 	 * eg  /usr/lib/fwflash/identify/ses.so
745a7763bfSjmcp 	 * is the identification plugin for devices attached to
755a7763bfSjmcp 	 * the host using the ses(7D) driver.
765a7763bfSjmcp 	 */
775a7763bfSjmcp 	char *filename;
785a7763bfSjmcp 
795a7763bfSjmcp 	/*
805a7763bfSjmcp 	 * The driver name that this plugin will search for in
815a7763bfSjmcp 	 * the device tree snapshot using di_drv_first_node(3DEVINFO)
825a7763bfSjmcp 	 * and di_drv_next_node(3DEVINFO).
835a7763bfSjmcp 	 */
845a7763bfSjmcp 	char *drvname; /* "ses" or "tavor" or .... */
855a7763bfSjmcp 
865a7763bfSjmcp 	/*
875a7763bfSjmcp 	 * Function entry point to support the command-line "-r"
885a7763bfSjmcp 	 * option - read image from device to persistent storage.
895a7763bfSjmcp 	 *
905a7763bfSjmcp 	 * Not all plugins and devices will support this operation.
915a7763bfSjmcp 	 */
925a7763bfSjmcp 	int (*fw_readfw)(struct devicelist *device, char *filename);
935a7763bfSjmcp 
945a7763bfSjmcp 	/*
955a7763bfSjmcp 	 * Function entry point to support the command-line "-f"
965a7763bfSjmcp 	 * option - writes from persistent storage to device
975a7763bfSjmcp 	 *
985a7763bfSjmcp 	 * All identification plugins must support this operation.
995a7763bfSjmcp 	 */
1005a7763bfSjmcp 	int (*fw_writefw)(struct devicelist *device, char *filename);
1015a7763bfSjmcp 
1025a7763bfSjmcp 	/*
1035a7763bfSjmcp 	 * Function entry point used to build the list of valid, flashable
1045a7763bfSjmcp 	 * devices attached to the system using the loadable module drvname.
1055a7763bfSjmcp 	 * (Not all devices attached using drvname will be valid for this
1065a7763bfSjmcp 	 * plugin to report.
1075a7763bfSjmcp 	 *
1085a7763bfSjmcp 	 * start allows us to display flashable devices attached with
1095a7763bfSjmcp 	 * different drivers and provide the user with a visual clue
1105a7763bfSjmcp 	 * that these devices are different to others that are detected.
1115a7763bfSjmcp 	 *
1125a7763bfSjmcp 	 * All identification plugins must support this operation.
1135a7763bfSjmcp 	 */
1145a7763bfSjmcp 	int (*fw_identify)(int start);
1155a7763bfSjmcp 
1165a7763bfSjmcp 	/*
1175a7763bfSjmcp 	 * Function entry point to support the command-line "-l"
1185a7763bfSjmcp 	 * option - list/report flashable devices attached to the system.
1195a7763bfSjmcp 	 *
1205a7763bfSjmcp 	 * All identification plugins must support this operation.
1215a7763bfSjmcp 	 */
1225a7763bfSjmcp 	int (*fw_devinfo)(struct devicelist *thisdev);
1235a7763bfSjmcp };
1245a7763bfSjmcp 
1255a7763bfSjmcp 
1265a7763bfSjmcp struct pluginlist {
1275a7763bfSjmcp 	/*
1285a7763bfSjmcp 	 * fully qualified filename in /usr/lib/fwflash/identify
1295a7763bfSjmcp 	 * made up of fwflash-[drivername].so
1305a7763bfSjmcp 	 *
1315a7763bfSjmcp 	 * eg  /usr/lib/fwflash/identify/ses.so
1325a7763bfSjmcp 	 * is the identification plugin for devices attached to
1335a7763bfSjmcp 	 * the host using the ses(7D) driver.
1345a7763bfSjmcp 	 */
1355a7763bfSjmcp 	char *filename;
1365a7763bfSjmcp 
1375a7763bfSjmcp 	/*
1385a7763bfSjmcp 	 * The driver name that this plugin will search for in
1395a7763bfSjmcp 	 * the device tree snapshot using di_drv_first_node(3DEVINFO)
1405a7763bfSjmcp 	 * and di_drv_next_node(3DEVINFO).
1415a7763bfSjmcp 	 */
1425a7763bfSjmcp 	char *drvname;
1435a7763bfSjmcp 
1445a7763bfSjmcp 	/*
1455a7763bfSjmcp 	 * pointer to the actual plugin, so we can access its
1465a7763bfSjmcp 	 * function entry points
1475a7763bfSjmcp 	 */
1485a7763bfSjmcp 	struct fw_plugin *plugin;
1495a7763bfSjmcp 
1505a7763bfSjmcp 	/* pointer to the next element in the list */
1515a7763bfSjmcp 	TAILQ_ENTRY(pluginlist) nextplugin;
1525a7763bfSjmcp };
1535a7763bfSjmcp 
1545a7763bfSjmcp struct vpr {
1555a7763bfSjmcp 	/* vendor ID, eg "HITACHI " */
1565a7763bfSjmcp 	char *vid;
1575a7763bfSjmcp 
1585a7763bfSjmcp 	/* product ID, eg "DK32EJ36NSUN36G " */
1595a7763bfSjmcp 	char *pid;
1605a7763bfSjmcp 
1615a7763bfSjmcp 	/* revision, eg "PQ08" */
1625a7763bfSjmcp 	char *revid;
1635a7763bfSjmcp 
1645a7763bfSjmcp 	/*
1655a7763bfSjmcp 	 * Additional, encapsulated identifying information.
1665a7763bfSjmcp 	 * This pointer allows us to add details such as the
1675a7763bfSjmcp 	 * IB hba sector size, which command set should be
1685a7763bfSjmcp 	 * used or a part number.
1695a7763bfSjmcp 	 */
1705a7763bfSjmcp 	void *encap_ident;
1715a7763bfSjmcp };
1725a7763bfSjmcp 
1735a7763bfSjmcp struct fwfile {
1745a7763bfSjmcp 	/*
1755a7763bfSjmcp 	 * The fully qualified filename. No default location for
1765a7763bfSjmcp 	 * for the firmware image file is mandated.
1775a7763bfSjmcp 	 */
1785a7763bfSjmcp 	char *filename;
1795a7763bfSjmcp 
1805a7763bfSjmcp 	/* Pointer to the identification plugin required */
1815a7763bfSjmcp 	struct fw_plugin *plugin;
1825a7763bfSjmcp 
1835a7763bfSjmcp 	/* pointer to the identification summary structure */
1845a7763bfSjmcp 	struct vpr *ident;
1855a7763bfSjmcp };
1865a7763bfSjmcp 
1875a7763bfSjmcp struct devicelist {
1885a7763bfSjmcp 	/*
1895a7763bfSjmcp 	 * fully qualified pathname, with /devices/.... prefix
1905a7763bfSjmcp 	 */
1915a7763bfSjmcp 	char *access_devname;
1925a7763bfSjmcp 
1935a7763bfSjmcp 	/*
1945a7763bfSjmcp 	 * Which drivername did we find this device attached with
1955a7763bfSjmcp 	 * in our device tree walk? Eg, ses or tavor or sgen...
1965a7763bfSjmcp 	 */
1975a7763bfSjmcp 	char *drvname;
1985a7763bfSjmcp 
1995a7763bfSjmcp 	/*
2005a7763bfSjmcp 	 * What class of device is this? For tavor-attached devices,
2015a7763bfSjmcp 	 * we set this to "IB". For other devices, unless there is
2025a7763bfSjmcp 	 * a common name to use, just make this the same as the
2035a7763bfSjmcp 	 * drvname field.
2045a7763bfSjmcp 	 */
2055a7763bfSjmcp 	char *classname;
2065a7763bfSjmcp 
2075a7763bfSjmcp 	/* pointer to the VPR structure */
2085a7763bfSjmcp 	struct vpr *ident;
2095a7763bfSjmcp 
2105a7763bfSjmcp 	/*
2115a7763bfSjmcp 	 * In the original fwflash(1M), it was possible to select a
2125a7763bfSjmcp 	 * device for flashing by using an index number called a
2135a7763bfSjmcp 	 * dev_num. We retain that concept for pluggable fwflash, with
2145a7763bfSjmcp 	 * the following change - whenever our identification plugin has
2155a7763bfSjmcp 	 * finished and found at least one acceptable device, we bump the
2165a7763bfSjmcp 	 * index number by 100. This provides the user with another key
2175a7763bfSjmcp 	 * to distinguish the desired device from a potentially very large
2185a7763bfSjmcp 	 * list of similar-looking devices.
2195a7763bfSjmcp 	 */
2205a7763bfSjmcp 	unsigned int index;
2215a7763bfSjmcp 
2225a7763bfSjmcp 	/*
2235a7763bfSjmcp 	 * Contains SAS or FC Port-WWNs, or IB GUIDS. Both SAS and FC only
2245a7763bfSjmcp 	 * need one entry in this array since they really only have one
2255a7763bfSjmcp 	 * address which we should track. IB devices can have 4 GUIDs
2265a7763bfSjmcp 	 * (System Image, Node Image, Port 1 and Port 2).
2275a7763bfSjmcp 	 */
2285a7763bfSjmcp 	char *addresses[4];
2295a7763bfSjmcp 
2305a7763bfSjmcp 	/*
2315a7763bfSjmcp 	 * Pointer to the plugin needed to flash this device, and
2325a7763bfSjmcp 	 * to use for printing appropriate device-specific information
2335a7763bfSjmcp 	 * as required by the "-l" option to fwflash(1M).
2345a7763bfSjmcp 	 */
2355a7763bfSjmcp 	struct fw_plugin *plugin;
2365a7763bfSjmcp 
2375a7763bfSjmcp 	/* Next entry in the list */
2385a7763bfSjmcp 	TAILQ_ENTRY(devicelist) nextdev;
2395a7763bfSjmcp };
2405a7763bfSjmcp 
2415a7763bfSjmcp 
2425a7763bfSjmcp /*
2435a7763bfSjmcp  * this type of plugin is for the firmware image vendor-specific
2445a7763bfSjmcp  * verification functions, which we load from FWVERIFYPLUGINDIR
2455a7763bfSjmcp  */
2465a7763bfSjmcp 
2475a7763bfSjmcp struct vrfyplugin {
2485a7763bfSjmcp 	/*
2495a7763bfSjmcp 	 * fully-qualified filename in /usr/lib/fwflash/verify,
2505a7763bfSjmcp 	 * made up of [drivername]-[vendorname].so
2515a7763bfSjmcp 	 *
2525a7763bfSjmcp 	 * eg  /usr/lib/fwflash/verify/ses-SUN.so
2535a7763bfSjmcp 	 * is the verification plugin for ses-attached devices which
2545a7763bfSjmcp 	 * have a vendorname of "SUN".
2555a7763bfSjmcp 	 */
2565a7763bfSjmcp 	char *filename;
2575a7763bfSjmcp 
2585a7763bfSjmcp 	/*
2595a7763bfSjmcp 	 * The vendor name, such as "SUN" or "MELLANOX"
2605a7763bfSjmcp 	 */
2615a7763bfSjmcp 	char *vendor;
2625a7763bfSjmcp 
2635a7763bfSjmcp 	/*
2645a7763bfSjmcp 	 * An opaque handle for dlopen()/dlclose() to use.
2655a7763bfSjmcp 	 */
2665a7763bfSjmcp 	void *handle;
2675a7763bfSjmcp 
2685a7763bfSjmcp 	/*
2695a7763bfSjmcp 	 * Firmware image size in bytes, as reported by
2705a7763bfSjmcp 	 * stat().
2715a7763bfSjmcp 	 */
2725a7763bfSjmcp 	unsigned int imgsize;
2735a7763bfSjmcp 
2745a7763bfSjmcp 	/*
2755a7763bfSjmcp 	 * Flashable devices frequently have different buffers
2765a7763bfSjmcp 	 * to use for different image types. We track the buffer
2775a7763bfSjmcp 	 * required for this particular image with this variable.
2785a7763bfSjmcp 	 *
2795a7763bfSjmcp 	 * Once the verifier has figured out what sort of image
2805a7763bfSjmcp 	 * it's been passed, it will know what value to use for
2815a7763bfSjmcp 	 * this variable.
2825a7763bfSjmcp 	 */
2835a7763bfSjmcp 	unsigned int flashbuf;
2845a7763bfSjmcp 
2855a7763bfSjmcp 	/*
2865a7763bfSjmcp 	 * Points to the entire firmware image in memory.
2875a7763bfSjmcp 	 * We do this so we can avoid multiple open()/close()
2885a7763bfSjmcp 	 * operations, and to make it easier for checksum
2895a7763bfSjmcp 	 * calculations.
2905a7763bfSjmcp 	 */
2915a7763bfSjmcp 	int *fwimage;
2925a7763bfSjmcp 
2935a7763bfSjmcp 	/*
2945a7763bfSjmcp 	 * We also store the name of the firmware file that
2955a7763bfSjmcp 	 * we point to with *fwimage. This is needed in cases
2965a7763bfSjmcp 	 * where we need to key off the name of the file to
2975a7763bfSjmcp 	 * determine whether a different buffer in the target
2985a7763bfSjmcp 	 * device should be targeted.
2995a7763bfSjmcp 	 *
3005a7763bfSjmcp 	 * For example, our "standard" firmware image (file.fw)
3015a7763bfSjmcp 	 * might require use of buffer id 0, but a boot image
3025a7763bfSjmcp 	 * (boot.fw) might require use of buffer id 17. In each
3035a7763bfSjmcp 	 * case, it is the verifier plugin that determines the
3045a7763bfSjmcp 	 * specific bufferid that is needed by that firmware image.
3055a7763bfSjmcp 	 */
3065a7763bfSjmcp 	char *imgfile;
3075a7763bfSjmcp 
3085a7763bfSjmcp 	/*
3095a7763bfSjmcp 	 * The verification function entry point. The code
3105a7763bfSjmcp 	 * in fwflash.c calls this function to verify that
3115a7763bfSjmcp 	 * the nominated firmware image file is valid for
3125a7763bfSjmcp 	 * the selected devicenode.
3135a7763bfSjmcp 	 *
3145a7763bfSjmcp 	 * Note that if the verification fails, the image
3155a7763bfSjmcp 	 * does _not_ get force-flashed to the device.
3165a7763bfSjmcp 	 */
3175a7763bfSjmcp 	int (*vendorvrfy)(struct devicelist *devicenode);
3185a7763bfSjmcp };
3195a7763bfSjmcp 
3205a7763bfSjmcp /* Flags for argument parsing */
3215a7763bfSjmcp #define	FWFLASH_HELP_FLAG	0x01
3225a7763bfSjmcp #define	FWFLASH_VER_FLAG	0x02
3235a7763bfSjmcp #define	FWFLASH_YES_FLAG	0x04
3245a7763bfSjmcp #define	FWFLASH_LIST_FLAG	0x08
3255a7763bfSjmcp #define	FWFLASH_CLASS_FLAG	0x10
3265a7763bfSjmcp #define	FWFLASH_DEVICE_FLAG	0x20
3275a7763bfSjmcp #define	FWFLASH_FW_FLAG		0x40
3285a7763bfSjmcp #define	FWFLASH_READ_FLAG	0x80
3295a7763bfSjmcp 
3305a7763bfSjmcp /* global variables for fwflash */
3315a7763bfSjmcp TAILQ_HEAD(PLUGINLIST, pluginlist);
3325a7763bfSjmcp TAILQ_HEAD(DEVICELIST, devicelist);
3335a7763bfSjmcp struct PLUGINLIST *fw_pluginlist;
3345a7763bfSjmcp struct DEVICELIST *fw_devices;
3355a7763bfSjmcp 
3365a7763bfSjmcp struct vrfyplugin *verifier;
3375a7763bfSjmcp di_node_t rootnode;
3385a7763bfSjmcp struct fw_plugin *self;
3395a7763bfSjmcp 
3405a7763bfSjmcp /*
3415a7763bfSjmcp  * utility defines and macros, since the firmware image we get
3425a7763bfSjmcp  * from LSI is ARM-format and that means byte- and short-swapping
3435a7763bfSjmcp  * on sparc
3445a7763bfSjmcp  */
3455a7763bfSjmcp 
3465a7763bfSjmcp #define	HIGHBITS16		0xff00
3475a7763bfSjmcp #define	HIGHBITS32		0xffff0000
3485a7763bfSjmcp #define	HIGHBITS64		0xffffffff00000000ULL
3495a7763bfSjmcp #define	LOWBITS16		0x00ff
3505a7763bfSjmcp #define	LOWBITS32		0x0000ffff
3515a7763bfSjmcp #define	LOWBITS64		0x00000000ffffffffULL
3525a7763bfSjmcp 
3535a7763bfSjmcp #if defined(_LITTLE_ENDIAN)
3545a7763bfSjmcp #define	ARMSWAPBITS(bs)		(bs)
355b3f3b44fSJames C. McPherson #define	MLXSWAPBITS16(bs)	ntohs(bs)
356b3f3b44fSJames C. McPherson #define	MLXSWAPBITS32(bs)	ntohl(bs)
3575a7763bfSjmcp #define	MLXSWAPBITS64(bs)	\
3585a7763bfSjmcp 	(BE_64(((bs) & LOWBITS64)) | BE_64(((bs) & HIGHBITS64)))
3595a7763bfSjmcp #else
3605a7763bfSjmcp #define	ARMSWAPBITS(bs)	(LE_32(((bs) & LOWBITS32)) | LE_32(((bs) & HIGHBITS32)))
3615a7763bfSjmcp #define	MLXSWAPBITS16(bs)	(bs)
3625a7763bfSjmcp #define	MLXSWAPBITS32(bs)	(bs)
3635a7763bfSjmcp #define	MLXSWAPBITS64(bs)	(bs)
3645a7763bfSjmcp #endif
3655a7763bfSjmcp 
3665a7763bfSjmcp /* common functions for fwflash */
367f1c23465SJames C. McPherson void logmsg(int severity, const char *msg, ...);
3685a7763bfSjmcp 
3695a7763bfSjmcp #ifdef __cplusplus
3705a7763bfSjmcp }
3715a7763bfSjmcp #endif
3725a7763bfSjmcp 
3735a7763bfSjmcp #endif /* _FWFLASH_H */
374