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