/*
 * netboot.h  -  Define the structure of the netboot specification (host)
 *
 * Copyright (C) 2003-2007 Gero Kuhlmann   <gero@gkminix.han.de>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: netboot.h,v 1.9 2007/01/06 18:30:52 gkminix Exp $
 */

#ifndef NETBOOT_H
#define NETBOOT_H


/*
 * Check the compile system and turn structure packing on
 */
#include <compiler.h>
#include <pack.h>



/*
 * The boot image has the following header in it's first sector
 */
#define NBHEADER_MAGIC	0x1B031336	/* Magic no for load header */
#define NBHEADER_SIG	0xAA55		/* Boot signature */
#define NBHEADER_SIZE	512		/* Size of boot image header */
#define FLAG1_KEEP_ALL	0x01		/* Keep UNDI and kernel */
#define FLAG1_KEEP_UNDI	0x02		/* Keep only UNDI */

#ifndef _ASSEMBLY_

struct load_header {
  __long         magic;			/* magic number */
  __u8           hlength;		/* length of header */
  __u8           hflags1;		/* header flags */
  __u8           hflags2;
  __u8           hflags3;
  __fptr         locn;			/* location of this header */
  __fptr         execute;		/* execution address */
  __u8           dummy[494];		/* up to full sector */
  __u16          bootsig;		/* boot signature */
} PACKED;

#define LH_KEEP_ALL(a)	(((a)->hflags1) & FLAG1_KEEP_ALL)
#define LH_KEEP_UNDI(a)	(((a)->hflags1) & FLAG1_KEEP_UNDI)
#define LH_HDRLEN(a)	((((a)->hlength) & 0x0F) << 2)
#define LH_VENDLEN(a)	((((a)->hlength) & 0xF0) >> 2)

#else

			.struct	0
boot_hd_magic:		.struct	.+4	# magic number
boot_hd_length:		.struct	.+1	# length of header in 16-bit words
boot_hd_flag1:		.struct	.+1	# header flags
boot_hd_flag2:		.struct	.+1
boot_hd_flag3:		.struct	.+1
boot_hd_locn:		.struct	.+4	# location of this header
boot_hd_exec:		.struct	.+4	# execution address
boot_hd_vendor:		.struct	.	# header vendor info

#endif /* _ASSEMBLY_ */



/*
 * In the header sector the load records are located, which actually tell
 * which part of the following image has to go where in memory
 */
#define BOOT_FLAG_B0	0x01		/* flags for load record */
#define BOOT_FLAG_B1	0x02
#define BOOT_FLAG_EOF	0x04

#define LOADER_TAG	16		/* generic tag for loader program */

#ifndef _ASSEMBLY_

struct load_record {
  __u8              rlength;		/* length of record */
  __u8              rtag1;		/* load record tags */
  __u8              rtag2;
  __u8              rflags;		/* load record flags */
  __lptr            address;		/* abs addr for part in mem */
  __long            ilength;		/* len of part in boot image */
  __long            mlength;		/* memory needed for part */
#ifdef USE_VENDOR
  union vendor_data vendor_data;	/* optional vendor data */
#endif
} PACKED;

#define LR_IS_B0(a)	(((a)->rflags) & BOOT_FLAG_B0)
#define LR_IS_B1(a)	(((a)->rflags) & BOOT_FLAG_B1)
#define LR_IS_EOF(a)	(((a)->rflags) & BOOT_FLAG_EOF)
#define LR_HDRLEN(a)	((((a)->rlength) & 0x0F) << 2)
#define LR_VENDLEN(a)	((((a)->rlength) & 0xF0) >> 2)

#else

			.struct	0
boot_ld_length:		.struct	.+1	# length of load record
boot_ld_tag1:		.struct	.+1	# load record tags
boot_ld_tag2:		.struct	.+1
boot_ld_flags:		.struct	.+1	# load record flags
boot_ld_addr:		.struct	.+4	# abs addr for part in memory
boot_ld_ilength:	.struct	.+4	# length of part in boot image
boot_ld_mlength:	.struct	.+4	# memory needed for part
boot_ld_vendor:		.struct	.	# optional vendor data

#endif /* _ASSEMBLY_ */



/*
 * According to the netboot specification, the bootrom should support
 * a so called services interrupt. This interrupt is supported even by
 * older bootroms, which don't support the PXE API.
 */
#if COMPILE_SYSTEM != COMPILER_HOST

#define NB_SERVICE_INT		0x78		/* bootrom service interrupt */
#define NB_SERVICE_MAGIC	0x4748		/* bootrom service magic ID */

#define NB_SERVICE_CHECK	0		/* function to check service */
#define NB_SERVICE_TERM		1		/* terminate bootrom service */
#define NB_SERVICE_GETUNDI	2		/* determine UNDI entry addr */

#if !defined(_ASSEMBLY_) && !defined(_BOOTROM_)
static inline unsigned short call_nb_service(short num)
{
  __u16 d0;

  __asm__ __volatile__(
	"int $0x78"
	: "=&a" (d0)
	: "0" ((__u16)((num << 8) & 0xFF00))
	: "memory", "cc");
  return((unsigned short)d0);
}
#endif
#endif



/*
 * Restore all definitions for data structure packing
 */
#include <unpack.h>

#endif

