#ifndef __EPI3_H__
#define __EPI3_H__

#define EPI3_SERIAL_LEN			19
#define EPI3_NUM_CHIP_REVISIONS		16
#define	EPI3_P_HW_MODLEV_MAX		65535
#define EPI3_P_MAGIC					0x55
#define	EPI3_P_MAGIC_EMPTY				0xff

#define PPR3_TOTAL_OEMS 9
#define PPR3_TOTAL_MFGS 22


#define SWAP_SHORT(x) \
      ((unsigned short)( \
      (((unsigned short)(x) & (unsigned short)0x00ffUL) << 8) | \
      (((unsigned short)(x) & (unsigned short)0xff00UL) >> 8) ))

typedef struct
{
	u8		epiChip[4];
	u8		epiChipRev[4];
} tEpi3ChipRev;

typedef struct
{
	u8		epiVersion;
	u8		epiMagicNumber;
	char		epiSerial[EPI3_SERIAL_LEN+1];
	u8		epiManufacturer;
	u8		epiYear;
	u8		epiMonth;
	u8		epiSpare1;
	u16		epiBoardId;
	u16		epiPcbRev;
	u8              epiMacAddress[6];
	char		epi844Bom[4]; /* whooooooooo momma, nasty! 
					in bootloader we have a 4 byte string which overlays 
					the old 845BOM and 820BOM fields. This is so we 
					can fit the X1-X19 text into the new 844bom field.
					this shouldn't be a problem because nothing else looks
					at these fields, just so long as the size of the
					structure doesn't change */
	tEpi3ChipRev	epiChipRevisions[EPI3_NUM_CHIP_REVISIONS];
	u16		epiOEM;
	u8		spare2[2];
	u8		spare3[80]; /* Make size up to 256 bytes */
	u16		epiChecksum;
	u16		HWModLevel;
} epi3Personality;


typedef struct
{
	u32 magic;
	u32 entrySize;
	u32 state;
	u32 nameOffset;
	u32 valueOffset;
} hwdb_entry_header;

typedef struct
{
	const u32 board_id;
	const char *board_name;
} compatible_device;

enum epi3_type {
	EPI3_TYPE_BASE = 1,
	EPI3_TYPE_XEM,
	EPI3_TYPE_PSU,
	EPI3_TYPE_EM,

	EPI3_TYPE_MAX
};

extern const char ppr3_oems[];
extern const char ppr3_mfgs[];
extern const char *ppr3_rev_names[];
extern const char *ppr3_proto_names[];
extern const int num_rev_names;
extern const int num_proto_names;


epi3Personality *epi3_getcurrent(void);
void		diag_epi3_reloc_names(void);
int	        epi3_dataok(epi3Personality * epi3Address);
u16	        epi3_checksum(epi3Personality *epi3Address);
int	        diag_epi3_display_baseboard_history(void);
void            diag_epi3_print_personality(epi3Personality *personality);
int     	 diag_epi3_personality_menu(char *strBuf, epi3Personality * last_personality);
int             diag_epi3mk_backend(int argc, char *argv[], epi3Personality *last_personality, epi3Personality *new_personality);
int             diag_epi3_xem_init(void);
int             diag_epi3_psu_init(void);
void            diag_epi3_module_init(void);
int             diag_epi3_module_submenu (enum epi3_type, int);
void		epi3_setmacaddr(void);
#endif
