This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] x86/Intel: fix indirect far jmp/call with operand size specified


"H.J. Lu" <hjl.tools@gmail.com> writes:

> On Thu, Feb 21, 2008 at 05:49:34PM +0100, Andreas Jaeger wrote:
>> "H.J. Lu" <hjl.tools@gmail.com> writes:
>> 
>> > Hi Jan,
>> >
>> > Do you have testcases?
>> 
>> netboot fails with:
>> 
>> runtime.S86: Assembler messages:
>> runtime.S86:388: Error: suffix or operands invalid for `jmp'
>> runtime.S86:393: Error: suffix or operands invalid for `jmp'
>> runtime.S86:398: Error: suffix or operands invalid for `jmp'
>> 
>
> Can you provide a preprocessed source with command line
> options to reproduce it?

The call is:
reger:/usr/src/packages/BUILD/netboot-0.10.2/mknbi-mgl/runtime> gcc -E -nostdinc -I/usr/src/packages/BUILD/netboot-0.10.2/include -I/usr/src/packages/BUILD/netboot-0.10.2/mknbi-mgl -x assembler-with-cpp -traditional-cpp -C -P -DHAVE_CONFIG_H -D_ASSEMBLY_ -D_TARGET_   -o runtime.s86 runtime.S86
reger:/usr/src/packages/BUILD/netboot-0.10.2/mknbi-mgl/runtime> /usr/i586-suse-linux/bin/as  -o runtime.o86 runtime.s86

runtime.S86: Assembler messages:
runtime.S86:388: Error: suffix or operands invalid for `jmp'
runtime.S86:393: Error: suffix or operands invalid for `jmp'
runtime.S86:398: Error: suffix or operands invalid for `jmp'

I'm appending the runtime.s86 file.

The lines with problems are the following:

	jmp	dword ptr cs:[oldi0]    # line 388

3:	cmp	si,0x0005
	jne	4f
	pop	si			# call old interrupt 4
	jmp	dword ptr cs:[oldi4]    # line 393

4:	cmp	si,0x0004
	jne	6f
	pop	si			# call old interrupt 5
	jmp	dword ptr cs:[oldi5]    # line 398


Andreas


/*
 * runtime.S86  -  MGL runtime module
 *
 * 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: runtime.S86,v 1.13 2007/01/06 18:31:38 gkminix Exp $
 *
 *====================================================================
 */

/*
 * rtcommon.i86  -  Common include file for MGL runtime module
 *
 * 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: rtcommon.i86,v 1.5 2007/01/06 18:31:38 gkminix Exp $
 */

/*
 * Can only get included into assembler source
 */



/*
 * Include various common include files
 */
/*
 * common.i86  -  general include file for target assembler files
 *
 * Copyright (C) 2002-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: common.i86,v 1.15 2007/01/06 18:30:52 gkminix Exp $
 */


/*
 * This file should only be included into target assembler files
 */


/*
 * We use 16-bit 386 code
 *
 * The .arch pseudo-opcode is not supported by all GAS versions. Those
 * which dont support it, do always assume i386 source code.
 */
.intel_syntax noprefix
.code16



/*
 *====================================================================
 *
 * Include version and configuration header file
 *
 * Note that these are the only files which can be safely included
 * into any host or target source file.
 */
/*
 * version.h  -  header file defining the version number
 *
 * Copyright (C) 1995-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: version.h.in,v 1.14 2007/01/06 18:30:52 gkminix Exp $
 */


/*
 * Define version and copyright information for the whole netboot
 * package.
 */


/* include/config.h.  Generated from config.h.in by configure.  */
/* include/config.h.in.  Generated from configure.ac by autoheader.  */

/* Specify file to include for Berkeley DB library */

/* Define to 1 if character set is EBCDIC */
/* #undef EBCDIC */

/* Define if GNU i386 assembler needs data32 prefix for movzx/movsx */
/* #undef GAS_NEED_DATA32 */

/* Define if GNU i386 assembler needs flat prefix for immediate values */
/* #undef GAS_NEED_FLAT */

/* Define if GNU i386 supports the "always_inline" function attribute */

/* Define if GNU i386 assembler supports .arch pseudo-opcode */

/* Define to 1 if you have the <arpa/inet.h> header file. */

/* Define to 1 if you have the <assert.h> header file. */

/* Define to 1 if you have the `atexit' function. */

/* Define to 1 if you have the `bcopy' function. */

/* Define if you have the Berkeley DB library, version 4 or newer */

/* Define to 1 if you have the `bzero' function. */

/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
   */

/* Define to 1 if you have the <dlfcn.h> header file. */

/* Define to 1 if you have the `flock' function. */

/* Define to 1 if you have the `getcwd' function. */

/* Define to 1 if you have the `getenv' function. */

/* Define to 1 if you have the <getopt.h> header file. */

/* Define to 1 if you have the `gettimeofday' function. */

/* Define to 1 if you have the `getwd' function. */
/* #undef HAVE_GETWD */

/* Define to 1 if you have the `gsignal' function. */
/* #undef HAVE_GSIGNAL */

/* Define to 1 if you have the `index' function. */

/* Define to 1 if intptr_t defined by <stdint.h> or <unistd.h> */

/* Define to 1 if you have the <inttypes.h> header file. */

/* Define to 1 if you have the <langinfo.h> header file. */

/* Define to 1 if you have the <limits.h> header file. */

/* Define to 1 if you have the <locale.h> header file. */

/* Define if you have the LZO compression library */

/* Define to 1 if you have the <malloc.h> header file. */

/* Define to 1 if you have the `memcmp' function. */

/* Define to 1 if you have the `memcpy' function. */

/* Define to 1 if you have the `memmove' function. */

/* Define to 1 if you have the <memory.h> header file. */

/* Define to 1 if you have the `memset' function. */

/* Define to 1 if you have the `mkdir' function. */

/* Define to 1 if you have the `mkstemp' function. */

/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
/* #undef HAVE_NDIR_H */

/* Define to 1 if you have the <netdb.h> header file. */

/* Define to 1 if you have the <netinet/in.h> header file. */

/* Define to 1 if you have the `nl_langinfo' function. */

/* Define if you have the unixODBC library */
/* #undef HAVE_ODBC */

/* Define to 1 if you have the `on_exit' function. */
/* #undef HAVE_ON_EXIT */

/* Define to 1 if you have the <paths.h> header file. */

/* Define to 1 if you have the `poll' function. */
/* #undef HAVE_POLL */

/* Define to 1 if you have the <pwd.h> header file. */

/* Define to 1 if you have the `raise' function. */

/* Define to 1 if you have the `rindex' function. */

/* Define to 1 if you have the `select' function. */

/* Define to 1 if you have the `setlocale' function. */

/* Define to 1 if you have the <stdint.h> header file. */

/* Define to 1 if you have the <stdlib.h> header file. */

/* Define to 1 if you have the `strchr' function. */

/* Define to 1 if you have the `strcspn' function. */

/* Define to 1 if you have the <strings.h> header file. */

/* Define to 1 if you have the <string.h> header file. */

/* Define to 1 if you have the `strncmp' function. */

/* Define to 1 if you have the `strrchr' function. */

/* Define to 1 if you have the `strspn' function. */

/* Define to 1 if you have the `strstr' function. */

/* Define to 1 if you have the `strtol' function. */

/* Define to 1 if you have the <sys/bitypes.h> header file. */

/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
   */
/* #undef HAVE_SYS_DIR_H */

/* Define to 1 if you have the <sys/file.h> header file. */

/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
   */
/* #undef HAVE_SYS_NDIR_H */

/* Define to 1 if you have the <sys/param.h> header file. */

/* Define to 1 if you have the <sys/poll.h> header file. */

/* Define to 1 if you have the <sys/select.h> header file. */

/* Define to 1 if you have the <sys/stat.h> header file. */

/* Define to 1 if you have the <sys/time.h> header file. */

/* Define to 1 if you have the <sys/types.h> header file. */

/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */

/* Define to 1 if you have the <unistd.h> header file. */

/* Define if GNU i386 supports the "used" function attribute */

/* Define to 1 if you have the `vasprintf' function. */

/* Define to 1 if you have the `vfprintf' function. */

/* Define to 1 if you have the `vsprintf' function. */

/* Define to 1 if you have the `wait3' function. */
/* #undef HAVE_WAIT3 */

/* Define to 1 if you have the `waitpid' function. */

/* Define if errno must be declared even when <errno.h> is included */
/* #undef NEED_DECLARATION_ERRNO */

/* Define to the address where bug reports for this package should be sent. */

/* Define to the full name of this package. */

/* Define to the full name and version of this package. */

/* Define to the one symbol short name of this package. */

/* Define to the version of this package. */

/* Define to 1 if the C compiler supports function prototypes. */

/* Define as the return type of signal handlers (`int' or `void'). */

/* The size of `int *', as computed by sizeof. */

/* Same value as SIZEOF_UNSIGNED_INT */

/* The size of `unsigned int', as computed by sizeof. */

/* The size of `unsigned long', as computed by sizeof. */

/* The size of `unsigned short', as computed by sizeof. */

/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
/* #undef STAT_MACROS_BROKEN */

/* Define to 1 if you have the ANSI C header files. */

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */

/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */

/* Set to the type your C compiler uses for 16 bit variables, for example
   'unsigned short'. If defined, this will override the type definitiones
   found in standard header files. */
/* #undef U16_TYPE */

/* Set to the type your C compiler uses for 32 bit variables, for example
   'unsigned long'. If defined, this will override the type definitiones found
   in standard header files. */
/* #undef U32_TYPE */

/* Set to the type your C compiler uses for 8 bit variables, for example
   'unsigned char'. If defined, this will override the type definitiones found
   in standard header files. */
/* #undef U8_TYPE */

/* Define if system cannot access misaligned data and has to use memcpy */
/* #undef USE_COPY */

/* Define version of LZO library to use */

/* Define if compiler supports __attribute__((packed)) */

/* Define if compiler supports pragma options align=packed */
/* #undef USE_PRAGMA_ALIGN */

/* Define if compiler supports pragma pack(1) */
/* #undef USE_PRAGMA_PACK */

/* Define if system has u_int8_t, u_int16_t and u_int32_t defined */

/* Define if system has __u8, __u16 and __u32 defined */
/* #undef USE__UXX */

/* Define to 1 if your processor stores words with the most significant byte
   first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */

/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
   `char[]'. */

/* Always include GNU extensions if available */

/* Define like PROTOTYPES; this can be used by system headers. */

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef gid_t */

/* Define to `__inline__' or `__inline' if that's what the C compiler
   calls it, or to nothing if 'inline' is not supported under any name.  */
/* #undef inline */

/* Define to `int' if <sys/types.h> does not define. */
/* #undef mode_t */

/* Define to `int' if <sys/types.h> does not define. */
/* #undef pid_t */

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef uid_t */

/* Define to empty if the keyword `volatile' does not work. Warning: valid
   code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */



/*
 *====================================================================
 *
 * Some older versions of GAS dont produce correct opcodes for the
 * variants of movzx and movsx, where a 16-bit value gets expanded
 * into a 32-bit value. Those GAS versions have to use the data32
 * prefix, and are identified by configure with GAS_NEED_DATA32. We
 * define macros here to allow for easy usage of these instructions.
 *
 * movzx32 macro
 */



/*
 * movsx32 macro
 */



/*
 * movsd32 macro
 */




/*
 *====================================================================
 *
 * When using Intel syntax with GAS, it is not possible to use symbols
 * as immediate values, like in:
 *
 *	.equ	t,2
 *
 *	mox	ax,t
 *
 * In this case, GAS treats `t' as a memory reference and assembles this
 * instruction as to move a word value from address 0x0002 into AX, which
 * is obviously wrong. In order to still be able to use the .equ or `='
 * instructions, we have to prepend the word FLAT in front of each use
 * of an immediate symbol. To make this easier we provide the following
 * macro.
 * However note that when using CPP macros to define numbers this is
 * not necessary. GAS treats numbers as op-code parameters always as
 * immediate values. Therefore
 *
 *	mov	ax,2
 *
 * will correctly load the immediate value 2 into AX. And since CPP
 * substitutes a macro name with a number, GAS will see a number
 * constant, and not a symbol.
 * Newer versions of GAS (2.16.90 and up) correctly process immediate
 * values (except for external symbols!!), and therefore don't need
 * the "flat" workaround, so we disable it with undefining GAS_NEED_FLAT.
 * For externals, we need to define a special workaround.
 *
 * To make it easier to distinguish between these cases in the source
 * code, we use upper-case names for CPP macros, and lower-case names
 * or names with a leading _ for GAS symbols.
 */




/*
 *====================================================================
 *
 * With Intel syntax, GAS is unable to use the tilde character for
 * a logical negation. We use the following macro instead.
 */




/*
 *====================================================================
 *
 * Convert C argument number into BP offset for standard stack frame
 */




/*
 *====================================================================
 *
 * Define the size and offsets of the pusha/pushad instructions on
 * the stack
 */





/*
 *====================================================================
 *
 * Definition of read-only data segment
 */




/*
 *====================================================================
 *
 * Define some external linker symbols.
 *
 * These are not standard symbols defined by the GNU linker, but will
 * be defined within the netboot linker script files.
 */

	.extern	__text_end		# end of text section
	.extern	__initext_end		# end of init text section
	.extern __data_start		# start of data section
	.extern	__data_end		# end of data section
	.extern	__bss_start		# start of BSS section
	.extern	__bss_end		# end of BSS section
	.extern	__file_size		# size of loadable file (e.g. text plus
					# data plus padding in between)

	.extern	__stack_size		# size of stack

	.extern	__heap_size		# size of heap


	.struct	0			# switch to absolute segment



/*
 * bios.i86  -  Definitions for accessing the system BIOS
 *
 * 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: bios.i86,v 1.7 2007/01/06 18:31:08 gkminix Exp $
 */



/*
 * Include the main C header file
 */
/* vim: set filetype=c:
 *
 * bios.h86  -  Definitions for acessing the system BIOS
 *
 * 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: bios.h86,v 1.12 2007/01/06 18:31:07 gkminix Exp $
 */



/*
 * This file can only get included into target C or assembler source files.
 */
/*
 * compiler.h  -  Define the type of compiler used for a source file
 *
 * 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: compiler.h,v 1.5 2007/01/06 18:30:52 gkminix Exp $
 */


/*
 * Many header files will be included into different source file types,
 * which all have to be cared for specially:
 *
 *   - host C compiler:   we must be sure to include all header files which
 *                        are required to define the target systems data types,
 *                        and all structures have to be packed
 *   - target C compiler: all header files for defining special data types have
 *                        to be included as well. However, the target C compiler
 *                        always packs all structures.
 *   - target assembler:  the data structures have to be defined as structure
 *                        offsets
 *
 * Define the allowed system types:
 */




/*
 * Check if we are using the host compiler. For all target source files, the
 * Makefiles define the _TARGET_ preprocessor token. If this is not defined,
 * and neither the _BOOTROM_ or __BCC__ tokens are defined, we can be pretty
 * sure that we are compiling a host-based source file.
 */



/*
 * If we are using GCC to produce a target file, _TARGET_ is defined by the
 * Makefiles, and __GNUC__ is defined by the preprocessor.
 */



/*
 * When using GAS to assemble target assembler source files, _ASSEMBLY_ has
 * been defined by the Makefiles.
 */



/*
 * Check if we are compiling in a valid environment
 */



/*
 * Check that we included a valid file for the current compile system
 */





/*
 * Include common header files according to the type of compile system
 */






/*
 * BIOS data segment
 */




/*
 * BIOS reset vector
 */



/*
 * BIOS bootstrap vector
 */



/*
 * BIOS system type ID byte
 */




/*
 * BIOS interrupt vectors:
 */



/*
 * Get an interrupt vector
 */



/*
 * Definitions for accessing a BIOS Diskette Parameter Block (DPB)
 */


			.struct	0
dpb_specify:		.struct	.+2	/* step rate, head un-/load time */
dpb_motordelay:		.struct	.+1	/* ticks until motor turned off */
dpb_sectsize:		.struct	.+1	/* bytes per sector */
dpb_sptrack:		.struct	.+1	/* sectors per track */
dpb_gaplength:		.struct	.+1	/* gap length in bytes */
dpb_datalength:		.struct	.+1	/* data length in bytes */
dpb_formatgap:		.struct	.+1	/* gap length for formatting */
dpb_fillerbyte:		.struct	.+1	/* format filler byte */
dpb_headsettle:		.struct	.+1	/* head settle time */
dpb_motorstart:		.struct	.+1	/* motor start time */






/*
 * BIOS interrupt 0x15, function 0xC0 returns various system configuration
 * values in the following structure:
 */

			.struct	0
romcfg_size:		.struct	.+2	/* size of this structure */
romcfg_model:		.struct	.+1	/* model byte */
romcfg_submodel:	.struct	.+1	/* submodel byte */
romcfg_revision:	.struct	.+1	/* revision byte */
romcfg_fb1:		.struct	.+1	/* feature byte 1 */
romcfg_fb2:		.struct	.+1	/* feature byte 2 */
romcfg_fb3:		.struct	.+1	/* feature byte 3 */






/*
 * BIOS interrupt 0x15, function 0xE820 returns system memory map descriptors
 * in the following structure:
 */

			.struct	0
sysmap_start:		.struct	.+8	/* start of memory block */
sysmap_end:		.struct	.+8	/* end of memory block */
sysmap_type:		.struct	.+4	/* type of memory block */





/*
 * bootp.i86  -  BOOTP record include file
 *
 * 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: bootp.i86,v 1.5 2007/01/06 18:30:54 gkminix Exp $
 */



/*
 * Include the C header file, which contains all necessary definitions
 */
/* vim: set filetype=c:
 *
 * bootp.h86  -  BOOTP record include file
 *
 * 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: bootp.h86,v 1.7 2007/01/06 18:30:54 gkminix Exp $
 */



/*
 * This file can only get included into target C or assembler source files.
 */
/*
 * compiler.h  -  Define the type of compiler used for a source file
 *
 * 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: compiler.h,v 1.5 2007/01/06 18:30:52 gkminix Exp $
 */


/*
 * Many header files will be included into different source file types,
 * which all have to be cared for specially:
 *
 *   - host C compiler:   we must be sure to include all header files which
 *                        are required to define the target systems data types,
 *                        and all structures have to be packed
 *   - target C compiler: all header files for defining special data types have
 *                        to be included as well. However, the target C compiler
 *                        always packs all structures.
 *   - target assembler:  the data structures have to be defined as structure
 *                        offsets
 *
 * Define the allowed system types:
 */



/*
 * Check if we are using the host compiler. For all target source files, the
 * Makefiles define the _TARGET_ preprocessor token. If this is not defined,
 * and neither the _BOOTROM_ or __BCC__ tokens are defined, we can be pretty
 * sure that we are compiling a host-based source file.
 */



/*
 * If we are using GCC to produce a target file, _TARGET_ is defined by the
 * Makefiles, and __GNUC__ is defined by the preprocessor.
 */



/*
 * When using GAS to assemble target assembler source files, _ASSEMBLY_ has
 * been defined by the Makefiles.
 */



/*
 * Check if we are compiling in a valid environment
 */



/*
 * Check that we included a valid file for the current compile system
 */





/*
 * Include common header files according to the type of compile system
 */






/*
 **************************************************************************
 *
 * Layout and magic ID of BOOTP/DHCP record. Refer to RFC 951,
 * RFC 1048 and RFC 1533 for further information.  The BOOTP/DHCP
 * record can be longer than the standard length as the bootrom
 * might be able to load a vendor extension file via tftp.
 */

/* RFC2132 vendor tags */

/* Option overload flags */

/* DHCP message types */

/* Client system architecture types */


/* BOOTP protocol opcodes */


/* BOOTP packet flags */


/* Vendor magic ID */


/*
 * BOOTP/DHCP packet.
 *
 * BOOTP_VENDOR_SIZE is calculated so that the whole BOOTP record is exactly
 * the size of an ethernet frame. However, RFC951 specifies a maximum size of
 * 64 bytes, while the vendor area can be as large as to fill up a full ether-
 * net frame with DHCP.
 *
 * BOOTP_MIN_SIZE is the minimum size a BOOTP record can have, e.g. the struc-
 * ture fields plus 64 bytes of vendor data area.
 *
 * BOOTP_MAX_SIZE is the upper limit a BOOTP/DHCP record can have. This arbi-
 * trarily set limit is to allow netboot clients to provide a predefined space
 * for storing a BOOTP/DHCP packet. The bootrom has to ensure that no BOOTP
 * buffer ever exceeds this limit. The only way to exceed this limit would be
 * to load an extra large BOOTP vendor extension file. The value has been
 * computed by adding 2048 (as a max. extension file size) to the size of a
 * RFC951 BOOTP record with a vendor data area size of 64 bytes. With DHCP
 * a vendor extension file is not supported, and therefore this limit can
 * never get exceeded with DHCP.
 */





		.struct	0
bootp_op:	.struct	.+1			# bootp OP-code
bootp_htype:	.struct	.+1			# hardware type
bootp_hlen:	.struct	.+1			# length of hardware addr
bootp_hops:	.struct	.+1			# hop-number
bootp_xid:	.struct	.+4			# transaction ID
bootp_secs:	.struct	.+2			# time since client booted
bootp_unused:	.struct	.+2	
bootp_ciaddr:	.struct	.+4			# client IP address
bootp_yiaddr:	.struct	.+4			# your (client) IP address
bootp_siaddr:	.struct	.+4			# server IP address
bootp_giaddr:	.struct	.+4			# BOOTP gateway IP address
bootp_chaddr:	.struct	.+16	# client hardware address
bootp_sname:	.struct	.+64	# server host name
bootp_file:	.struct	.+128	# boot file name
bootp_vend:	.struct	.+1264	# optional vendor information




/*
 **************************************************************************
 *
 * PXE vendor extension fields
 */

/* PXE vendor tags */


/* PXE boot server types */

/* Discovery flags bit masks */



/*
 **************************************************************************
 *
 * Netboot vendor extension fields
 */

/* PXE vendor tags */





/*
 * runtime.i86  -  Definitions for MGL runtime module
 *
 * 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: runtime.i86,v 1.8 2007/01/06 18:31:38 gkminix Exp $
 */



/*
 * Now include the main header file.
 */
/*
 * runtime.h  -  Definitions for MGL runtime module
 *
 * 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: runtime.h,v 1.11 2007/01/06 18:31:38 gkminix Exp $
 *
 */



/*
 * Check the compile system and turn structure packing on
 */
/*
 * compiler.h  -  Define the type of compiler used for a source file
 *
 * 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: compiler.h,v 1.5 2007/01/06 18:30:52 gkminix Exp $
 */


/*
 * Many header files will be included into different source file types,
 * which all have to be cared for specially:
 *
 *   - host C compiler:   we must be sure to include all header files which
 *                        are required to define the target systems data types,
 *                        and all structures have to be packed
 *   - target C compiler: all header files for defining special data types have
 *                        to be included as well. However, the target C compiler
 *                        always packs all structures.
 *   - target assembler:  the data structures have to be defined as structure
 *                        offsets
 *
 * Define the allowed system types:
 */



/*
 * Check if we are using the host compiler. For all target source files, the
 * Makefiles define the _TARGET_ preprocessor token. If this is not defined,
 * and neither the _BOOTROM_ or __BCC__ tokens are defined, we can be pretty
 * sure that we are compiling a host-based source file.
 */



/*
 * If we are using GCC to produce a target file, _TARGET_ is defined by the
 * Makefiles, and __GNUC__ is defined by the preprocessor.
 */



/*
 * When using GAS to assemble target assembler source files, _ASSEMBLY_ has
 * been defined by the Makefiles.
 */



/*
 * Check if we are compiling in a valid environment
 */



/*
 * Check that we included a valid file for the current compile system
 */





/*
 * Include common header files according to the type of compile system
 */



/*
 * pack.h  -  Enable structure packing
 *
 * 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: pack.h,v 1.5 2007/01/06 18:30:52 gkminix Exp $
 */


/*
 * We need to know about the compiler environment
 */



/*
 * To compile source files on the host which contains definitions for the
 * target system, structures have to be packed. Some compilers need pragmas
 * to do this.
 */




/*
 * The runtime module contains a structure at the beginning which contains
 * various operating parameters.
 */



			.struct	0
rtdata_id:		.struct	.+2	/* offset to ID string */
rtdata_loadsize:	.struct	.+4	/* total load size */
rtdata_textend:		.struct	.+2	/* end of runtime text seg */
rtdata_dataend:		.struct	.+2	/* end of runtime data seg */
rtdata_bssend:		.struct	.+2	/* end of runtime BSS seg */
rtdata_constend:	.struct	.+2	/* end of constant data */
rtdata_varend:		.struct	.+2	/* end of variable data */
rtdata_dataofs:		.struct	.+2	/* offset to data segment */
rtdata_debug:		.struct	.+2	/* offset to debugging data */
rtdata_start:		.struct	.+2	/* offset to first screen */
rtdata_stksize:		.struct	.+2	/* size of stack */




/*
 * Minimum, maximum and default stack sizes for runtime module
 */



/*
 * Error codes returned by the runtime module
 */



/*
 * Mapping of compare commands for runtime module. These are needed
 * for the strcmp routine.
 */



/*
 * Definitions for exports table
 */





			.struct	0
rtexport_exptype:	.struct	.+1	/* type of export record */
rtexport_valtype:	.struct	.+1	/* type of value */
rtexport_value:		.struct	.+2	/* symbol value */
rtexport_size:		.struct	.+2	/* symbol value */
rtexport_name:		.struct	.+2	/* offset to name */
rtexport_args:		.struct	.+2	/* offset to arguments */




/*
 * Restore all definitions for data structure packing
 */
/*
 * unpack.h  -  Restore all definitions about structure packing
 *
 * 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: unpack.h,v 1.5 2007/01/06 18:30:52 gkminix Exp $
 */

/*
 * We need to know about the compiler environment
 */



/*
 * To compile source files on the host which contains definitions for the
 * target system, structures have to be packed. The following restore the
 * normal host compiler behaviour of non-packing all structures.
 */





/*
 * The runtime module can be loaded by different methods: from a netboot
 * or PXE bootrom, or while running under DOS. The following structure is
 * used to pass all necessary parameters from the loader to the runtime
 * module.
 */
		.struct	0
rtload_flags:	.struct	.+2		/* flags (see below) */
rtload_bsize:	.struct	.+2		/* size of BOOTP record */
rtload_bootp:	.struct	.+4		/* far pointer to BOOTP record */
rtload_pxe:	.struct	.+4		/* far pointer to !PXE structure */








/*
 * Include the C header file, which contains all necessary definitions
 */
/* vim: set filetype=c:
 *
 * rtcommon.h86  -  Common include file for MGL runtime module
 *
 * 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: rtcommon.h86,v 1.17 2007/01/06 18:31:38 gkminix Exp $
 */






/*
 *****************************************************************************
 *
 * Error codes returned by the load function
 */



/*
 *****************************************************************************
 *
 * Error codes. The upper byte of each error code identifies the error
 * source.
 */

/* Special flag to avoid scanning through user exception handlers */

/* Code range 0x00: general runtime errors */

/* Code range 0x01: loader errors */



/*
 *****************************************************************************
 *
 * Global definitions
 */



/*
 *****************************************************************************
 *
 * Global variables
 */



/*
 *****************************************************************************
 *
 * Global functions
 */



/*
 *****************************************************************************
 *
 * Functions get called differently by code produced with the MGL compiler
 * compared to code produced by GCC. While MGL always pushes words, GCC
 * always pushes double-words. Also the order of the arguments is different,
 * and MGL expects the called routine to pop it's own arguments from the stack.
 * While some of these differences can be tuned with GCC attributes, it is
 * much easier to use wrapper routines (see __PUBLIC macro below).
 * Those wrapper routines provide the GCC routines with a pointer to the
 * arguments passed by the MGL program. This pointer points to an opaque
 * array of bytes. In order to make ordinary GCC arguments out of these bytes,
 * we use the following macro.
 */



/*
 *****************************************************************************
 *
 * Macro to stringify a macro expansion value
 */



/*
 *****************************************************************************
 *
 * Macros to help with generating values for the exports table
 */



/*
 *****************************************************************************
 *
 * Macros to generate argument lists
 */



/*
 *****************************************************************************
 *
 * Macros to generate function definitions
 */



/*
 *****************************************************************************
 *
 * Macros to generate export information
 */



/*
 *****************************************************************************
 *
 * Call next exit function
 */



/*
 *****************************************************************************
 *
 * Macros to convert characters to/from ISO-8859-1 character set.
 */




/*
 * general.i86  -  Common PXE definitions
 *
 * 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: general.i86,v 1.7 2007/01/06 18:31:04 gkminix Exp $
 */



/*
 * Include the C header file, which contains all necessary definitions
 */
/* vim: set filetype=c:
 *
 * general.h86  -  Common PXE definitions
 *
 * 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: general.h86,v 1.11 2007/01/06 18:31:04 gkminix Exp $
 */



/*
 * Include the main header file
 */
/* vim: set filetype=c:
 *
 * general.h  -  Common PXE definitions
 *
 * 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: general.h,v 1.5 2007/01/06 18:31:03 gkminix Exp $
 */



/*
 * Check the compile system and turn structure packing on
 */
/*
 * compiler.h  -  Define the type of compiler used for a source file
 *
 * 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: compiler.h,v 1.5 2007/01/06 18:30:52 gkminix Exp $
 */


/*
 * Many header files will be included into different source file types,
 * which all have to be cared for specially:
 *
 *   - host C compiler:   we must be sure to include all header files which
 *                        are required to define the target systems data types,
 *                        and all structures have to be packed
 *   - target C compiler: all header files for defining special data types have
 *                        to be included as well. However, the target C compiler
 *                        always packs all structures.
 *   - target assembler:  the data structures have to be defined as structure
 *                        offsets
 *
 * Define the allowed system types:
 */



/*
 * Check if we are using the host compiler. For all target source files, the
 * Makefiles define the _TARGET_ preprocessor token. If this is not defined,
 * and neither the _BOOTROM_ or __BCC__ tokens are defined, we can be pretty
 * sure that we are compiling a host-based source file.
 */



/*
 * If we are using GCC to produce a target file, _TARGET_ is defined by the
 * Makefiles, and __GNUC__ is defined by the preprocessor.
 */



/*
 * When using GAS to assemble target assembler source files, _ASSEMBLY_ has
 * been defined by the Makefiles.
 */



/*
 * Check if we are compiling in a valid environment
 */



/*
 * Check that we included a valid file for the current compile system
 */





/*
 * Include common header files according to the type of compile system
 */



/*
 * pack.h  -  Enable structure packing
 *
 * 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: pack.h,v 1.5 2007/01/06 18:30:52 gkminix Exp $
 */


/*
 * We need to know about the compiler environment
 */



/*
 * To compile source files on the host which contains definitions for the
 * target system, structures have to be packed. Some compilers need pragmas
 * to do this.
 */




/*
 **************************************************************************
 *
 * This file contains the Preboot API common definitions as
 * per Intels PXE specification version 2.1.
 *
 **************************************************************************
 *
 * CPU types (defined in WfM 1.1):
 */



/*
 **************************************************************************
 *
 * Bus types (defined in WfM 1.1):
 */



/*
 * Restore all definitions for data structure packing
 */
/*
 * unpack.h  -  Restore all definitions about structure packing
 *
 * 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: unpack.h,v 1.5 2007/01/06 18:30:52 gkminix Exp $
 */

/*
 * We need to know about the compiler environment
 */



/*
 * To compile source files on the host which contains definitions for the
 * target system, structures have to be packed. The following restore the
 * normal host compiler behaviour of non-packing all structures.
 */






/*
 **************************************************************************
 *
 * This file contains the Preboot API common definitions as
 * per Intels PXE specification version 2.1.
 *
 **************************************************************************
 *
 * Result codes returned in AX by a PXENV API service:
 */



/*
 **************************************************************************
 *
 * Status codes returned in the status word of the PXENV API parameter
 * structure. Some of these codes are also used to return status
 * information from a boot image loader back to the bootrom.
 */

/* Generic API errors that are reported by the loader */

/* ARP/UDP errors (0x10 to 0x1F) */

/* BIOS/system errors (0x20 to 0x2F) */

/* TFP errors (0x30 to 0x3F) */

/* BOOTP errors (0x40 to 0x4F) */

/* DHCP errors (0x50 to 0x5F) */

/* Driver errors (0x60 to 0x6F) */

/* Bootstrap (.1) errors (0x70 to 0x7F) */

/* Environment (.2) errors (0x80 to 0x8F) */

/* MTFTP errors (0x90 to 0x9F) */

/* Misc. errors (0xA0 to 0xAF) */

/* BUSD errors (0xB0 to 0xBF) */

/* Loader errors (0xC0 to 0xCF) */

/* Reserved errors (0xD0 to 0xFF) */



/*
 **************************************************************************
 *
 * Define calls to the target runtime library. These routines should not be
 * used by the bootrom.
 */





.file "runtime.S86"
.line 29



/*
 *====================================================================
 *
 * Definitions local to this module
 */




.line 45
/*
 *====================================================================
 *
 * Define the text segment. This segment can start at any offset depending
 * on the loader used. The mknbi-mgl bootrom loader loads this program
 * at offset 0, while DOS loads this program at offset 0x0100.
 */

	.text

	.extern	prcrlf			# externals from runtime library
	.extern	prnstr
	.extern	prnnum
	.extern	keycheck
	.extern	keyget
	.extern	brk
	.extern	sbrk
	.extern	initpxe

	.extern	_init_bootp		# external initialization routines
	.extern	_init_console
	.extern	_init_net

	.extern	_rtint_raise		# external exception handler

	.global	_start			# global routines
	.global	_rtint_exit
	.global	_rtint_error
	.global	_rtint_chkstk

_start:	jmp	start



/*
 *====================================================================
 *
 * The header of the runtime module serves two purposes: first it gives
 * the compiler certain information about the size and location of various
 * parts of the runtime module, and secondly the compiler will give some
 * information back like the size of the produced code, etc.
 */

	.org	0x0008

rtinfo:	.word	rtid			# offset to ID string
	.long	0			# total load size of program
	.word	__text_end		# end of runtime text segment
	.word	__data_end		# end of runtime data segment
	.word	__bss_end		# end of runtime BSS segment
	.word	0			# end of constant data
	.word	0			# end of variable data
	.word	__initext_end		# offset to data segment
	.word	exptable		# offset to debugging data/export table
	.word	0			# start address
	.word	(8 * 1024)		# default stack size

newds:	.word	0			# new data segment
oldi0:	.long	0			# old interrupt vectors
oldi4:	.long	0
oldi5:	.long	0

rtid:	.asciz	"mglruntime"		# runtime ID string



/*
 *====================================================================
 *
 * Here the actual game starts. This program gets called by a loader
 * which passes the pointer to an information structure in ES:SI.
 * In this program we can be sure to run on a 386+ processor.
 */
start:	push	ds
	push	es			# save the BOOTP record pointer
	push	si
	call	1f			# compute code offset
1:	pop	ax
	sub	ax,offset 1b
	mov	bx,ax			# save code offset in BX
	mov	dx,cs			# convert code segment so that
	shr	ax,4			# it starts at a zero offset
	add	dx,ax			# save code segment in DX

	mov	ax,cs:rtdata_dataofs[bx + rtinfo]
	shr	ax,4
	add	ax,dx
	mov	ds,ax
	mov	es,ax
	mov	cs:[bx + newds],ax	# save it for later

	cld
	xor	ax,ax
	mov	di,cs:rtdata_constend[bx + rtinfo]
	mov	cx,cs:rtdata_varend[bx + rtinfo]
	sub	cx,di
	inc	cx			# clear variable data area
	shr	cx,1
	rep	stosw

	std
	mov	di,cs:rtdata_constend[bx + rtinfo]
	mov	cx,di
	dec	di
	sub	cx,cs:rtdata_bssend[bx + rtinfo]
	mov	si,cs:rtdata_dataend[bx + rtinfo]
	add	si,cx
	dec	si			# copy constant data area into
	rep	movsb			# proper position

	cld
	mov	di,cs:rtdata_dataend[bx + rtinfo]
	mov	cx,cs:rtdata_bssend[bx + rtinfo]
	sub	cx,di
	rep	stosb			# clear BSS segment
	pop	dword ptr [infoptr]	# save the info record pointer

	push	dx			# push new code segment value
	mov	ax,offset 2f		# change into new code segment
	push	ax
	lret

2:	cli
	mov	word ptr [oldstack + 0],sp
	mov	word ptr [oldstack + 2],ss
	mov	ax,ds			# set new stack
	mov	ss,ax
	mov	sp,0xFFFE
	mov	word ptr [stktop],sp	# save top of stack pointer
	sti
	nop				# necessary for some debuggers

/*
 * Check for PXE support
 */

	push	es
	les	bx,[infoptr]
	les	bx,es:rtload_pxe[bx]
	call	initpxe			# initialize PXE support
	pop	es
	or	ax,ax
	jnz	4f			# check if we have PXE installed
	inc	byte ptr [_havepxe]

/*
 * Check for flags passed to us by the runtime loader. If the trap flag
 * has not been set, disable all INT3 instructions.
 */

4:	push	es
	les	bx,[infoptr]
	mov	eax,es:rtload_bootp[bx]
	mov	[_btpptr],eax
	mov	ax,es:rtload_bsize[bx]
	mov	[_btplen],ax
	mov	ax,es:rtload_flags[bx]
	pop	es
	test	ax,0x0001
	setnz	byte ptr [_canload]
	test	ax,0x0002
	setnz	byte ptr [_canrun]
	test	ax,0x0004
	setnz	byte ptr [_canchange]
	test	ax,0x0008
	jz	3f
	jmp	0f

	.align	8
	.ascii	"trapadr$"		# string to find the trap address in
					# the runtime binary
trapaddr:
	.word	0			# address where to trap into the
					# debugger

0:	int3				# trap into debugger to allow changing
	nop				# the trap address
	mov	si,offset traplist
1:	mov	bx,cs:[si]		# scan through list of int3
	or	bx,bx			# instructions
	jz	3f
	mov	byte ptr cs:[bx],0xCC	# replace it with a INT3 instruction
	add	si,2
	jmp	1b


traplist:
	.word	trap1			# list of int3 instruction
	.word	trap2			# addresses
	.word	trap3
	.word	0


/*
 * This is required for GCC, which may use EBP for other purposes than
 * a stack pointer.
 */

3:	xor	ebp,ebp

/*
 * Setup all interrupt vectors required for the user program
 */

	cli
	push	es
	xor	ax,ax
	mov	es,ax
	mov	eax,dword ptr es:[(0 * 4)]
	mov	dword ptr cs:[oldi0],eax
	mov	eax,dword ptr es:[(4 * 4)]
	mov	dword ptr cs:[oldi4],eax
	mov	eax,dword ptr es:[(5 * 4)]
	mov	dword ptr cs:[oldi5],eax

	mov	word ptr es:[(0 * 4) + 0],cs
	mov	word ptr es:[(4 * 4) + 0],cs
	mov	word ptr es:[(5 * 4) + 0],cs
	mov	word ptr es:[(0 * 4) + 2],offset rtint0
	mov	word ptr es:[(4 * 4) + 2],offset rtint4
	mov	word ptr es:[(5 * 4) + 2],offset rtint5
	pop	es
	sti

/*
 * Set the stack size and the correct beginning of the heap
 */

	mov	ax,cs:rtdata_stksize[rtinfo]
	mov	[stksiz],ax
	mov	ax,cs:rtdata_varend[rtinfo]
	call	brk			# set new heap pointer
	cmp	ax,-1			# check that we have enough memory
	jne	6f

5:	mov	ax,0x0006 + 0x8000
	call	_rtint_raise

6:	mov	ax,[stktop]
	sub	ax,[stksiz]		# compute stack base
	jc	5b
	mov	[stkbase],ax

/*
 * Call module initialization routines. Note that the network
 * initialization routine has to come first!
 */

	call	_init_net
	call	_init_bootp
	call	_init_console
trap1:	nop				# gets replaced by int3

/*
 * Now call the user program. It should never return except for a
 * runtime error. The normal program termination is via the "load"
 * system call. Note that the user program expects the direction
 * flag cleared all the time.
 */

	cld
	mov	ax,word ptr cs:rtdata_start[rtinfo]
	call	ax
	mov	bx,2	# prepare return value

/*
 * Call all cleanup routines
 */

doexit:
trap2:	nop				# gets replaced by int3
	xor	ax,ax
	mov	[rtaddr],ax
	xchg	ax,[_atexit]		# check if cleanup routine defined
	or	ax,ax
	jz	7f
	xchg	ax,bx
	movzx	eax,ax
	call	bx			# call daisy-chained cleanup routines
	mov	bx,ax

/*
 * Restore all interrupt vectors
 */

7:	cli
	push	es
	xor	ax,ax
	mov	es,ax
	mov	eax,cs:dword ptr [oldi0]
	mov	dword ptr es:[(0 * 4)],eax
	mov	eax,cs:dword ptr [oldi4]
	mov	dword ptr es:[(4 * 4)],eax
	mov	eax,cs:dword ptr [oldi5]
	mov	dword ptr es:[(5 * 4)],eax
	pop	es
	sti

/*
 * After restoring the stack, return to the caller via a far return
 */

8:	cli
	mov	ss,word ptr [oldstack + 2]
	mov	sp,word ptr [oldstack + 0]
	sti				# restore stack and return to
	mov	ax,bx			# caller
	pop	ds
	lret



/*
 *====================================================================
 *
 * Handle runtime errors
 * Input:  none
 * Output: none
 * Registers changed: all (routine doesnt return)
 */
rtint0:	push	si
	mov	si,0x0003		# division by zero
	jmp	1f

rtint4:	push	si
	mov	si,0x0005		# integer overflow
	jmp	1f

rtint5:	push	si
	mov	si,0x0004		# bounds error
1:	push	ax
	push	bp
	mov	bp,sp
	mov	ax,cs
	cmp	ax,[bp + 8]		# check if the error was produced by
	pop	bp			# our own program
	pop	ax
	je	6f

	cmp	si,0x0003
	jne	3f
	pop	si			# call old interrupt 0
	jmp	dword ptr cs:[oldi0]

3:	cmp	si,0x0005
	jne	4f
	pop	si			# call old interrupt 4
	jmp	dword ptr cs:[oldi4]

4:	cmp	si,0x0004
	jne	6f
	pop	si			# call old interrupt 5
	jmp	dword ptr cs:[oldi5]

/*
 * Process a runtime error in our own program
 */

6:	sti
	pop	ax
	mov	ax,cs:[newds]		# this is just for safety
	mov	ds,ax
	mov	es,ax
	mov	ax,si
	jmp	_rtint_raise		# raise an exception



/*
 *====================================================================
 *
 * Check the stack pointer and set the runtime address. This routine
 * gets called by all routines callable from the user program.
 * Input:  AX   -  Required stack size
 * Output: None
 * Registers changed: None
 */
_rtint_chkstk:

	push	bp
	push	ax
	mov	bp,sp
	mov	ax,[bp + 6]		# save return address
	sub	ax,3
	mov	[rtaddr],ax
	sub	bp,[bp + 0]
	jc	1f
	cmp	bp,[stkbase]		# check that we have enough stack
	ja	3f			# space

1:	xor	ax,ax			# determine top of heap space
	call	sbrk
	cmp	ax,bp			# if the stack already grew into the
	mov	ax,0x0007		# heap, the user exception info might
	jb	2f			# be destroyed, so we dont allow scan-
	add	ax,0x8000	# ning the user handlers in that case.
2:	call	_rtint_raise

3:	mov	ax,[rtaddr]
	cmp	ax,cs:[trapaddr]	# check if we have to call the
	jne	9f			# debugger trap
trap3:	nop				# gets replaced by int3

9:	pop	ax
	pop	bp
	ret


_rtproc_chkstk:
	push	bp
	mov	bp,sp
	mov	ax,[bp + 4]			# get required stack size
	pop	bp
	call	_rtint_chkstk			# call checking routine
	ret	2



/*
 *====================================================================
 *
 * Terminate the program
 * Input:  AX  -  Return code
 * Output: None
 * Registers changed: all (routine does not return)
 */
_rtint_exit:

	pop	bx			# discard return address
	mov	bx,ax
	jmp	doexit			# terminate the program


_rtproc_exit:

	pop	bx			# discard return address
	mov	bx,2
	jmp	doexit			# terminate the program



/*
 *====================================================================
 *
 * Print a runtime error
 * Input:  AX  -  Pointer to error string
 * Output: None
 * Registers changed: all (routine does not return)
 */
_rtint_error:

	pop	bx			# discard return address
	push	ax
	mov	si,offset rterr
	call	prnstr			# print error message
	pop	si
	call	prnstr

	cld
	mov	si,[debugptr]
	or	si,si			# check if we have a debugging info
	jz	8f			# table
	mov	bx,[rtaddr]
	or	bx,bx			# check if we have a valid address
	jz	8f
	xor	cx,cx
2:	lodsw				# scan through the debug table to
	or	ax,ax			# find the address
	jz	7f
	cmp	ax,bx
	ja	7f
	lodsw
	mov	cx,ax			# remember last line number
	jmp	2b

7:	jcxz	8f			# check if we found a line number
	mov	si,offset linerr
	call	prnstr
	movzx	eax,cx			# print the line number
	call	prnnum

8:	call	prcrlf
	mov	si,offset keyerr	# print "keypress" message
	call	prnstr
	call	keycheck		# clear keyboard buffer
	call	keyget			# wait for a key press
9:	mov	bx,2	# indicate error return
	jmp	doexit			# terminate the program





/*
 *====================================================================
 *
 * Export table
 */
	.section .initext

exptable:


/*
 * Version information
 */

	.byte	1		# type of export record
	.byte	2		# version information is string type
	.word	(0 * 256 + 2)
	.word	0
	.asciz	"Interface Version"	# name of record


/*
 * "exit" routine
 */
	.byte	2		# type of export record
	.byte	0		# return type
	.word	_rtproc_exit		# offset to routine
	.word	0			# number of arguments
	.asciz	"exit"			# name of routine


/*
 * "chkstk" routine
 */
	.byte	2		# type of export record
	.byte	0		# return type
	.word	_rtproc_chkstk		# offset to routine
	.word	1			# number of arguments
	.asciz	"chkstk"		# name of routine
	.byte	2		# 1st arg: number
	.byte	0		# 1st arg: passed by value




/*
 *====================================================================
 *
 * Data area
 */
	.section .rodata


/* Copyright message */
cpyrgt:	.ascii	"MGL runtime module "
	.ascii	"Version 0.10.2 (netboot)"
	.byte	0x0D, 0x0A
	.ascii	"Copyright (C) 1995-2007 G. Kuhlmann"
	.byte	0x0D, 0x0A
	.byte	0x0D, 0x0A
	.byte	0


/* Error messages */
rterr:	.asciz	"Runtime error: "
linerr:	.asciz	" at line "
keyerr:	.asciz	"Press any key to continue"




/*
 *====================================================================
 *
 * Data segment
 */
	.data

	.extern	stksiz			# stack size for i386 library




/*
 *====================================================================
 *
 * BSS segment
 */
	.bss


/* Global variables for the runtime module */

	.global	_atexit
	.global	_btpptr
	.global	_btplen
	.global	_canload
	.global	_canrun
	.global	_canchange
	.global	_havepxe

	.lcomm	_atexit,2		# pointer to first cleanup routine
	.lcomm	_btpptr,4		# pointer to bootrom BOOTP buffer
	.lcomm	_btplen,2		# size of bootrom BOOTP buffer
	.lcomm	_canload,1		# flag if we accept 0
	.lcomm	_canrun,1		# flag if we accept 1
	.lcomm	_canchange,1		# flag if we accept BOOTP changes
	.lcomm	_havepxe,1		# flag if we have PXE support


/* Local variables */

	.global	stktop			# required for i386 library

	.align	2
	.lcomm	rtaddr,2		# current runtime address
	.lcomm	infoptr,4		# pointer to info record
	.lcomm	stktop,2		# pointer to top of stack
	.lcomm	stkbase,2		# pointer to base of stack
	.lcomm	debugptr,2		# pointer to debugging info
	.lcomm	oldstack,4		# old stack from caller




/*
 *====================================================================
 */
	.end

-- 
 Andreas Jaeger, Director Platform/openSUSE, aj@suse.de
  SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
   Maxfeldstr. 5, 90409 Nürnberg, Germany
    GPG fingerprint = 93A3 365E CE47 B889 DF7F  FED1 389A 563C C272 A126

Attachment: pgp00000.pgp
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]