#ifndef __COMMON_H
#define __COMMON_H
/* 
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) Hewlett-Packard (Paul Bame) paul_bame@hp.com
 */

#define PALOMAGIC "PALO"
#define PALOVERSION "2.27"

#ifndef __ASSEMBLY__

#define  __KERNEL_STRICT_NAMES /* fixes build on SUSE 10 (kernel 2.6.1[2|3]) */

#if !(defined(__hpux__) || defined(__hpux))
# include <sys/cdefs.h>	/* useful macros */
# include <byteswap.h>
#endif

#include <stdarg.h>

/* Swap bytes in 32 bit value.  */
#define __palo_bswap_constant_32(x) \
	((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) | \
	 (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))

#if defined(__linux__)
# include <asm/byteorder.h>
#elif defined(__hpux__) || defined(__hpux)
/* HP-UX is always big endian */
# define __be64_to_cpu(x)	(x)
# define __be32_to_cpu(x)	(x)
# define __be16_to_cpu(x)	(x)
# define __le32_to_cpu(x)	__palo_bswap_constant_32(x)
# define __le16_to_cpu(x)	le16toh(x)
# define __cpu_to_be32(x)	(x)
#else /* BSD and similiar */
# include <endian.h>
# define __be64_to_cpu(x)	be64toh(x)
# define __be32_to_cpu(x)	be32toh(x)
# define __be16_to_cpu(x)	be16toh(x)
# define __le32_to_cpu(x)	le32toh(x)
# define __le16_to_cpu(x)	le16toh(x)
# define __cpu_to_be32(x)	htobe32(x)
#endif
#include "part.h"

#if defined(IPL_LOADER)
void *pa_memcpy(void *dest, const void *src, unsigned n);
#else
# include <string.h>
# define pa_memcpy memcpy
#endif

/* Newer versions of linux-kernel-headers provide a sanitized swab.h
 * which uses GLIBC provided functionality, and dump the kernel provided
 * ones. Include <byteswap.h> above, and provide compatibility #define's
 * to work around this. 
 */
#ifndef __swab64
#define __swab64(x)	bswap_64(x)
#endif /* __swab64 */

#ifndef __swab32
#define __swab32(x)	bswap_32(x)
#endif /* __swab32 */

#ifndef __swab16
#define __swab16(x)	bswap_16(x)
#endif /* __swab16 */

/* size of I/O block used in HP firmware */
#define FW_BLOCKSIZE	2048

#define MAX_IO_LIMIT	(4 * 1024 * 1024)	/* max. MB to read per IO */

#define GB	(1024 * 1024 * 1024)

/* assume kernel will always be loaded into the "lower" physical memory */
#define PHYS(virtual)	((virtual) & 0x0fffffff)

/* This struct is placed at the start of the boot loader executable.  The
 * "magic" number is the assembly-language branch needed to skip over the
 * rest of the structure.  This structure is manipulated by the program
 * which creates and updates boot media (palo).  It must stay 256 bytes
 * in length!
 *
 * kern_sz = 0 or rd_sz = 0 means no kern or ramdisk respectively.
 */
#define PALOHDRVERSION 5

#define PFLAG_INSTALL 0x1
#define PFLAG_EXT2    0x2

#define CMDLINELEN 1024		/* max length of command line */

struct firstblock
{
    unsigned char lifmagic0;	/* 0x80 */
    unsigned char lifmagic1;	/* 0x00 */

    char palomagic[5];		/* PALO */
    unsigned char version;
    int      kern32_offset;	/* seek() here to begin loading kernel */
    int      kern32_sz;		/* # bytes to load */
    int      rd_offset;		/* seek() here to begin loading ramdisk */
    int      rd_sz;		/* # bytes in ramdisk */
    char     cmdline_old[128];	/* OLD: Up to 127 bytes of text plus a \0 */

    unsigned char pad1[0xf0 - 8 - 9 * sizeof (int) - 128];
    int      kern32_native_sz;	/* 32bit kernel: uncompressed file size */
    int      kern64_native_sz;	/* 64bit kernel: uncompressed file size */
    unsigned int flags;
    int	     kern64_offset;
    int      kern64_sz;

    int ipl_addr;		/* offset 0xf0 */
    int ipl_size;
    int ipl_entry;

    /* offset 0x1be */
    unsigned char pad2[0x1be - (0xf0 + 3 * sizeof (int))];
    struct partition part[4];
    /* offset 0x1fe */
    unsigned char dosmagic[2];	/* 0x55, 0xaa */
    unsigned char pad4[1024 - 0x200];
    char     cmdline[CMDLINELEN];/* max 1023 bytes of text plus a \0 */
};

/* we use this so that we can do without the ctype library */
#define is_digit(c)	((c) >= '0' && (c) <= '9')

struct diskpartition
{
    /* in honor of the MBR scheme, these are in 512-byte sectors */
    __u64 start;
    /* length == 0 means nothing's here */
    __u64 length;
    unsigned char id;
};


#define MAXPARTS 16

extern int disk_2gb_limit;

int seekread(int fd, char *buf, unsigned nbytes, __u64 devaddr);
#define STRUCTWRITE(f, data, where) seekwrite((f), (char *)&data, sizeof data, (where))
#define STRUCTREAD(f, data, where) seekread((f), (char *)&data, sizeof data, (where))
#define GZIP_STRUCTREAD(loadable, f, data, where)			\
	(loadable->uncompressed_data) ?					\
		( pa_memcpy(&data, &loadable->uncompressed_data[where], sizeof data), (sizeof data) )  \
	: 								\
		seekread((f), (char *)&data, sizeof data, (where))

/* diskpart.c */
extern int is_extended(int id);
extern int load_partitions(int bootdev, struct diskpartition *mptab, int maxparts);
extern void print_ptab_pretty(struct diskpartition *mptab, int maxparts);

#endif /* __ASSEMBLY__ */
#endif /* __COMMON_H */
