/*
 * first.i86  -  constants for assembler module
 *
 * Copyright (C) 1995-2007 Gero Kuhlmann   <gero@gkminix.han.de>
 * Copyright (C) 1996,1997 Gero Kuhlmann   <gero@gkminix.han.de>
 *                and Markus Gutschke <gutschk@math.uni-muenster.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: first.i86,v 1.7 2007/01/06 18:31:26 gkminix Exp $
 *
 *====================================================================
 *
 * This file can also be included into host source files:
 */
#if !defined(_ASSEMBLY_) || !defined(_TARGET_)
# if !defined(MKNBI_H_LINUX) || !defined(COMMON_H) || !defined(PACK_ENABLED)
#  error This file can only be included into mknbi.h
# endif
#endif



/*
 *====================================================================
 *
 * Size of a disk sector. This definition is needed all over the
 * place.
 */
#define SECTSIZE	 512



/*
 *====================================================================
 *
 * Definitions for allocating dynamic memory, which is used to hold
 * temporary working buffers.
 *
 * The MAX_MEM segment address must be within the range of addresses
 * contained in MIN_MEM number of kB.
 */
#ifndef MKNBI_H_LINUX

#define LINUX_MEM	0x9000		/* Standard Linux load segment */
#define HIGH_MEM	0x9A00		/* Highest Linux seg (see boot.txt) */
#define MAX_MEM		0x8000		/* Max usable segment (see SPEC.DOC) */
#define BASE_MEM	0x1000		/* Base seg for low-loading kernel */

#define MIN_MEM		(HIGH_MEM / 64)	/* Minimum number of kB of base mem */
#define MIN_EXT		0x00000C00	/* Minimum number of kB of ext mem */

#define LINUX_HEAP	2048		/* Size of linux setup heap */
#define CMDL_SIZE	2048		/* Size of static command line memory */

					/* Segment of Linux setup */
#define SETUP_SEG	(LINUX_MEM + (SECTSIZE / 16))
					/* Maximum size of static memory */
#define MAX_STATIC_SIZE	((HIGH_MEM - LINUX_MEM) * 16)

/* These two constants are predefined within the Linux kernel */
#define KERNEL_LD_HIGH	0x00100000	/* kernel high load address */
#define KERNEL_LD_LOW	0x00001000	/* kernel low load address */

#define MAX_PATH_LEN	1024		/* Maximum length of path name */
#define MAX_ADDRS_LEN	 512		/* Maximum length of IP addr string */

#endif



/*
 *====================================================================
 *
 * Vendor information for the boot rom image.
 */
#ifdef _ASSEMBLY_

			.struct	0
boot_ld_rdflags:	/* union */	/* flags for ramdisk loading */
boot_ld_krnflags:	.struct	.+1	/* kernel flags */

#include <netboot.i86>

#else

#define USE_VENDOR

union vendor_data {
  __u8       rdflags;			/* flags for rd loading */
  __u8       krnflags;			/* kernel flags */
} PACKED;

#include <netboot.h>

#endif


/* Vendor magic ID and definition of load record numbers */
#define VENDOR_MAGIC	"GK-mknbi-linux" /* vendor ID */
#define VENDOR_SIZE	4		/* size of vendor ID in dwords */

#define BOOTLNUM	0		/* primary boot loader */
#define CMDLNUM		1		/* command line */
#define INITNUM		2		/* floppy boot sector */
#define SETUPNUM	3		/* kernel setup */
#define KERNELNUM	4		/* kernel image */
#define RAMDISKNUM	5		/* ramdisk image */
#define NUM_RECORDS	6



/*
 *====================================================================
 *
 * Ramdisk images can be loaded in three different ways:
 *  RD_AUTO  --  The ramdisk image is loaded at either 0x100000 or right
 *               behind the kernel image; at run-time it will be moved
 *               to the end of physical memory or right before 0x1000000.
 *               This technique guarantees maximum compatibility with
 *               broken BIOS versions without making assumptions on the
 *               way, the bootrom determined the end of memory. The
 *               drawback is, that moving the image costs some extra time.
 *  RD_EOM   --  The ramdisk image is loaded right before the end of
 *               physical memory. It is the bootroms responsibility to do
 *               this reliably. This might cause problems with some ancient
 *               BIOS versions, if the computer is equipped with more then
 *               16M of main memory.
 *  RD_FIXED --  The user provided a fixed load address for the ramdisk
 *               image. This entails possible compatibility restrictions
 *               when moving the image from one client to another. OTOH,
 *               it could be the final solution if everything else fails...
 */
#define RD_NONE		-1
#define RD_AUTO		 0
#define RD_EOM		 1
#define RD_FIXED	 2

#define RD_MAXFLAG	 2



/*
 *====================================================================
 *
 * Kernel vendor flags
 *
 *  KRN_USE_IP --  Newer kernels (above 2.2.x) use "ip=" instead of
 *                 "nfsaddrs=" on the command line. They should also
 *                 never remove this option if "kernel" is given as
 *                 the argument. We use this flag to tell the boot
 *                 loader.
 *  KRN_NFS_IP --  Kernel versions 2.4.x and above need the address
 *                 of the NFS server at the beginning of the nfsroot
 *                 command line option
 *  KRN_LOW    --  The kernel has to be copied into low memory
 */
#define KRN_USE_IP	0x01
#define KRN_NFS_IP	0x02
#define KRN_LOW		0x04



/*
 *====================================================================
 *
 * Define some special BOOTP vendor tags
 */
#ifndef MKNBI_H_LINUX

#define VEND_RFC_VID	128		/* Vendor tag: magic identification */
#define VEND_RFC_CMDAD	129		/* Addition to kernel command line */
#define VEND_RFC_RDEV	130		/* Device by which to find root FS */
#define VEND_RFC_VSEL	176		/* index to user selected image */

#define BOOTP_VID_ID	0x687445E4

#endif



/*
 *====================================================================
 *
 * The command line descriptor is placed in the floppy boot sector area
 * and looks like this:
 *
 * 0x90020-0x90021     2 bytes   command line magic number
 * 0x90022-0x90023     2 bytes   command line offs. relative to floppy boot sec
 * 0x901FA-0x901FB     2 bytes   video mode
 */
#ifndef MKNBI_H_LINUX

#define CL_MAGIC_ADDR	0x20		/* command line magic number */
#define CL_MAGIC	0xA33F		/* very unusual command sequence */
#define CL_OFFSET	0x22		/* command line offset */
#define VGA_OFFSET	0x1FA		/* video mode */

#endif



/*
 *====================================================================
 *
 * The setup-header has to be changed in order to tell the kernel about a
 * loaded ramdisk image
 *
 * This only works with Linux kernels 1.3.73 or above; that is why the
 * setup magic number and the setup version number need to be verified
 * before relying on the layout of this data structure.
 */
#ifndef _ASSEMBLY_

struct setup_header {
  __u8          jump[2];
  __u8          magic[4];		/* "HdrS" */
  __u16         version;		/* >= 0x0201 for initrd */
  __u8          realmode_swtch[4];
  __u16         start_sys_seg;
  __u16         kernel_version;
  __u8          type_of_loader;
  __u8          loadflags;
  __u16         setup_move_size;
  struct i_long code32_start;
  struct i_long ramdisk_image;
  struct i_long ramdisk_size;
  struct i_long bootsect_kludge;
  __u16         heap_end_ptr;
  __u16         pad1;
  struct i_long cmd_line_ptr;
  struct i_long initrd_addr_max;
} PACKED;

#else

			.struct	0

su_jump:		.struct	.+2
su_magic:		.struct	.+4		/* setup magic number */
su_version:		.struct	.+2		/* setup version number */
su_realmode_switch:	.struct	.+4
su_sys_seg:		.struct	.+2		/* seg of low-loaded kernel */
su_kernel_version:	.struct	.+2		/* kernel version number */
su_type_of_loader:	.struct	.+1		/* type of loader */
su_load_flags:		.struct	.+1		/* load flags */
su_move_size:		.struct	.+2		/* setup move size */
su_32_start:		.struct	.+4		/* protected mode start addr */
su_ramdisk_start:	.struct	.+4		/* ramdisk start address */
su_ramdisk_size:	.struct	.+4		/* ramdisk size */
su_bootsect_kludge:	.struct	.+4		/* floppy loader helper */
su_heap:		.struct	.+2		/* heap pointer */
su_pad1:		.struct	.+2
su_cmdl_ptr:		.struct	.+4		/* pointer to command line */
su_initrd_addr:		.struct	.+4		/* pointer to initrd ramdisk */

#endif

#define SETUP_MAGIC		0x53726448
#define SETUP_MAGIC_STR		"HdrS"

#define SETUP_TYPE_LILO		0x00
#define SETUP_TYPE_LOADLIN	0x10
#define SETUP_TYPE_BOOTSECT	0x20
#define SETUP_TYPE_SYSLX	0x30
#define SETUP_TYPE_NETBOOT	0x41
#define SETUP_MY_TYPE		SETUP_TYPE_NETBOOT

#define SETUP_VERSION_OLD	0x0201
#define SETUP_VERSION_NEW	0x0202

#define SETUP_LDFLAGS_HIGH	0x01
#define SETUP_LDFLAGS_HEAP	0x80



/*
 *====================================================================
 *
 * Predefined kernel command line option names
 */
#define NFS_ROOT	"nfsroot="		/* nfsroot option for kernel */
#define NFS_ADDRS	"nfsaddrs="		/* nfsaddrs option for kernel */
#define NFS_IP		"ip="			/* ip option for kernel */
#define VGA_ARG		"vga="			/* VGA mode argument */
#define ROOT_ARG	"root="			/* root device */
#define INIT_ARG	"init="			/* init program argument */



/*
 *====================================================================
 *
 * Special VGA mode values
 */
#define VGA_NORMAL	-1
#define VGA_EXTENDED	-2
#define VGA_ASK		-3
#define VGA_DEFAULT	-4
#define VGA_NONE	-5

#define VGA_MIN		-3		/* Minimum value */
#define VGA_MAX		0x7FFF		/* Maximum value */


