summaryrefslogtreecommitdiff
path: root/gpxe/src/arch/i386/prefix
diff options
context:
space:
mode:
Diffstat (limited to 'gpxe/src/arch/i386/prefix')
-rw-r--r--gpxe/src/arch/i386/prefix/bootpart.S218
-rw-r--r--gpxe/src/arch/i386/prefix/dskprefix.S381
-rw-r--r--gpxe/src/arch/i386/prefix/hdprefix.S109
-rw-r--r--gpxe/src/arch/i386/prefix/hromprefix.S12
-rw-r--r--gpxe/src/arch/i386/prefix/kkpxeprefix.S13
-rw-r--r--gpxe/src/arch/i386/prefix/kpxeprefix.S9
-rw-r--r--gpxe/src/arch/i386/prefix/libprefix.S819
-rw-r--r--gpxe/src/arch/i386/prefix/lkrnprefix.S216
-rw-r--r--gpxe/src/arch/i386/prefix/mbr.S13
-rw-r--r--gpxe/src/arch/i386/prefix/nbiprefix.S77
-rw-r--r--gpxe/src/arch/i386/prefix/nullprefix.S13
-rw-r--r--gpxe/src/arch/i386/prefix/pxeprefix.S761
-rw-r--r--gpxe/src/arch/i386/prefix/romprefix.S1079
-rw-r--r--gpxe/src/arch/i386/prefix/undiloader.S49
-rw-r--r--gpxe/src/arch/i386/prefix/unnrv2b.S184
-rw-r--r--gpxe/src/arch/i386/prefix/unnrv2b16.S9
-rw-r--r--gpxe/src/arch/i386/prefix/usbdisk.S23
-rw-r--r--gpxe/src/arch/i386/prefix/xromprefix.S9
18 files changed, 0 insertions, 3994 deletions
diff --git a/gpxe/src/arch/i386/prefix/bootpart.S b/gpxe/src/arch/i386/prefix/bootpart.S
deleted file mode 100644
index 968da1a3..00000000
--- a/gpxe/src/arch/i386/prefix/bootpart.S
+++ /dev/null
@@ -1,218 +0,0 @@
-FILE_LICENCE ( GPL2_OR_LATER )
-
-#define BOOT_SEG 0x07c0
-#define EXEC_SEG 0x0100
-#define STACK_SEG 0x0200
-#define STACK_SIZE 0x2000
-
- .text
- .arch i386
- .section ".prefix", "awx", @progbits
- .code16
-
-/*
- * Find active partition
- *
- * Parameters:
- * %dl : BIOS drive number
- * %bp : Active partition handler routine
- */
-find_active_partition:
- /* Set up stack at STACK_SEG:STACK_SIZE */
- movw $STACK_SEG, %ax
- movw %ax, %ss
- movw $STACK_SIZE, %sp
-
- /* Relocate self to EXEC_SEG */
- pushw $BOOT_SEG
- popw %ds
- pushw $EXEC_SEG
- popw %es
- xorw %si, %si
- xorw %di, %di
- movw $0x200, %cx
- rep movsb
- ljmp $EXEC_SEG, $1f
-1: pushw %ds
- popw %es
- pushw %cs
- popw %ds
-
- /* Check for LBA extensions */
- movb $0x41, %ah
- movw $0x55aa, %bx
- stc
- int $0x13
- jc 1f
- cmpw $0xaa55, %bx
- jne 1f
- movw $read_lba, read_sectors
-1:
- /* Read and process root partition table */
- xorb %dh, %dh
- movw $0x0001, %cx
- xorl %esi, %esi
- xorl %edi, %edi
- call process_table
-
- /* Print failure message */
- movw $10f, %si
- jmp boot_error
-10: .asciz "Could not locate active partition\r\n"
-
-/*
- * Print failure message and boot next device
- *
- * Parameters:
- * %si : Failure string
- */
-boot_error:
- cld
- movw $0x0007, %bx
- movb $0x0e, %ah
-1: lodsb
- testb %al, %al
- je 99f
- int $0x10
- jmp 1b
-99: /* Boot next device */
- int $0x18
-
-/*
- * Process partition table
- *
- * Parameters:
- * %dl : BIOS drive number
- * %dh : Head
- * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
- * %ch : Low eight bits of cylinder
- * %esi:%edi : LBA address
- * %bp : Active partition handler routine
- *
- * Returns:
- * CF set on error
- */
-process_table:
- pushal
- call read_boot_sector
- jc 99f
- movw $446, %bx
-1: call process_partition
- addw $16, %bx
- cmpw $510, %bx
- jne 1b
-99: popal
- ret
-
-/*
- * Process partition
- *
- * Parameters:
- * %dl : BIOS drive number
- * %dh : Head
- * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
- * %ch : Low eight bits of cylinder
- * %esi:%edi : LBA address
- * %bx : Offset within partition table
- * %bp : Active partition handler routine
- */
-process_partition:
- pushal
- /* Load C/H/S values from partition entry */
- movb %es:1(%bx), %dh
- movw %es:2(%bx), %cx
- /* Update LBA address from partition entry */
- addl %es:8(%bx), %edi
- adcl $0, %esi
- /* Check active flag */
- testb $0x80, %es:(%bx)
- jz 1f
- call read_boot_sector
- jc 99f
- jmp *%bp
-1: /* Check for extended partition */
- movb %es:4(%bx), %al
- cmpb $0x05, %al
- je 2f
- cmpb $0x0f, %al
- je 2f
- cmpb $0x85, %al
- jne 99f
-2: call process_table
-99: popal
- /* Reload original partition table */
- call read_boot_sector
- ret
-
-/*
- * Read single sector to %es:0000 and verify 0x55aa signature
- *
- * Parameters:
- * %dl : BIOS drive number
- * %dh : Head
- * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
- * %ch : Low eight bits of cylinder
- * %esi:%edi : LBA address
- *
- * Returns:
- * CF set on error
- */
-read_boot_sector:
- pushw %ax
- movw $1, %ax
- call *read_sectors
- jc 99f
- cmpw $0xaa55, %es:(510)
- je 99f
- stc
-99: popw %ax
- ret
-
-/*
- * Read sectors to %es:0000
- *
- * Parameters:
- * %dl : BIOS drive number
- * %dh : Head
- * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
- * %ch : Low eight bits of cylinder
- * %esi:%edi : LBA address
- * %ax : Number of sectors (max 127)
- *
- * Returns:
- * CF set on error
- */
-read_sectors: .word read_chs
-
-read_chs:
- /* Read sectors using C/H/S address */
- pushal
- xorw %bx, %bx
- movb $0x02, %ah
- stc
- int $0x13
- sti
- popal
- ret
-
-read_lba:
- /* Read sectors using LBA address */
- pushal
- movw %ax, (lba_desc + 2)
- pushw %es
- popw (lba_desc + 6)
- movl %edi, (lba_desc + 8)
- movl %esi, (lba_desc + 12)
- movw $lba_desc, %si
- movb $0x42, %ah
- int $0x13
- popal
- ret
-
-lba_desc:
- .byte 0x10
- .byte 0
- .word 1
- .word 0x0000
- .word 0x0000
- .long 0, 0
diff --git a/gpxe/src/arch/i386/prefix/dskprefix.S b/gpxe/src/arch/i386/prefix/dskprefix.S
deleted file mode 100644
index 60d351f7..00000000
--- a/gpxe/src/arch/i386/prefix/dskprefix.S
+++ /dev/null
@@ -1,381 +0,0 @@
-/* NOTE: this boot sector contains instructions that need at least an 80186.
- * Yes, as86 has a bug somewhere in the valid instruction set checks.
- *
- */
-
-/* floppyload.S Copyright (C) 1991, 1992 Linus Torvalds
- * modified by Drew Eckhardt
- * modified by Bruce Evans (bde)
- *
- * floppyprefix.S is loaded at 0x0000:0x7c00 by the bios-startup routines.
- *
- * It then loads the system at SYSSEG<<4, using BIOS interrupts.
- *
- * The loader has been made as simple as possible, and continuous read errors
- * will result in a unbreakable loop. Reboot by hand. It loads pretty fast by
- * getting whole tracks at a time whenever possible.
- */
-
-FILE_LICENCE ( GPL2_ONLY )
-
-.equ BOOTSEG, 0x07C0 /* original address of boot-sector */
-
-.equ SYSSEG, 0x1000 /* system loaded at SYSSEG<<4 */
-
- .org 0
- .arch i386
- .text
- .section ".prefix", "ax", @progbits
- .code16
-
- jmp $BOOTSEG, $go /* reload cs:ip to match relocation addr */
-go:
- movw $0x2000-12, %di /* 0x2000 is arbitrary value >= length */
- /* of bootsect + room for stack + 12 for */
- /* saved disk parm block */
-
- movw $BOOTSEG, %ax
- movw %ax,%ds
- movw %ax,%es
- movw %ax,%ss /* put stack at BOOTSEG:0x4000-12. */
- movw %di,%sp
-
-/* Many BIOS's default disk parameter tables will not recognize multi-sector
- * reads beyond the maximum sector number specified in the default diskette
- * parameter tables - this may mean 7 sectors in some cases.
- *
- * Since single sector reads are slow and out of the question, we must take care
- * of this by creating new parameter tables (for the first disk) in RAM. We
- * will set the maximum sector count to 36 - the most we will encounter on an
- * ED 2.88. High doesn't hurt. Low does.
- *
- * Segments are as follows: ds=es=ss=cs - BOOTSEG
- */
-
- xorw %cx,%cx
- movw %cx,%es /* access segment 0 */
- movw $0x78, %bx /* 0:bx is parameter table address */
- pushw %ds /* save ds */
-/* 0:bx is parameter table address */
- ldsw %es:(%bx),%si /* loads ds and si */
-
- movw %ax,%es /* ax is BOOTSECT (loaded above) */
- movb $6, %cl /* copy 12 bytes */
- cld
- pushw %di /* keep a copy for later */
- rep
- movsw /* ds:si is source, es:di is dest */
- popw %di
-
- movb $36,%es:4(%di)
-
- movw %cx,%ds /* access segment 0 */
- xchgw %di,(%bx)
- movw %es,%si
- xchgw %si,2(%bx)
- popw %ds /* restore ds */
- movw %di, dpoff /* save old parameters */
- movw %si, dpseg /* to restore just before finishing */
- pushw %ds
- popw %es /* reload es */
-
-/* Note that es is already set up. Also cx is 0 from rep movsw above. */
-
- xorb %ah,%ah /* reset FDC */
- xorb %dl,%dl
- int $0x13
-
-/* Get disk drive parameters, specifically number of sectors/track.
- *
- * It seems that there is no BIOS call to get the number of sectors. Guess
- * 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
- * 15 if sector 15 can be read. Otherwise guess 9.
- */
-
- movw $disksizes, %si /* table of sizes to try */
-
-probe_loop:
- lodsb
- cbtw /* extend to word */
- movw %ax, sectors
- cmpw $disksizes+4, %si
- jae got_sectors /* if all else fails, try 9 */
- xchgw %cx,%ax /* cx = track and sector */
- xorw %dx,%dx /* drive 0, head 0 */
- movw $0x0200, %bx /* address after boot sector */
- /* (512 bytes from origin, es = cs) */
- movw $0x0201, %ax /* service 2, 1 sector */
- int $0x13
- jc probe_loop /* try next value */
-
-got_sectors:
- movw $msg1end-msg1, %cx
- movw $msg1, %si
- call print_str
-
-/* ok, we've written the Loading... message, now we want to load the system */
-
- movw $SYSSEG, %ax
- movw %ax,%es /* segment of SYSSEG<<4 */
- pushw %es
- call read_it
-
-/* This turns off the floppy drive motor, so that we enter the kernel in a
- * known state, and don't have to worry about it later.
- */
- movw $0x3f2, %dx
- xorb %al,%al
- outb %al,%dx
-
- call print_nl
- pop %es /* = SYSSEG */
-
-/* Restore original disk parameters */
- movw $0x78, %bx
- movw dpoff, %di
- movw dpseg, %si
- xorw %ax,%ax
- movw %ax,%ds
- movw %di,(%bx)
- movw %si,2(%bx)
-
- /* Everything now loaded. %es = SYSSEG, so %es:0000 points to
- * start of loaded image.
- */
-
- /* Jump to loaded copy */
- ljmp $SYSSEG, $start_runtime
-
-endseg: .word SYSSEG
- .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
- .ascii "ADDW"
- .long endseg
- .long 16
- .long 0
- .previous
-
-/* This routine loads the system at address SYSSEG<<4, making sure no 64kB
- * boundaries are crossed. We try to load it as fast as possible, loading whole
- * tracks whenever we can.
- *
- * in: es - starting address segment (normally SYSSEG)
- */
-read_it:
- movw $0,sread /* load whole image including prefix */
- movw %es,%ax
- testw $0x0fff, %ax
-die: jne die /* es must be at 64kB boundary */
- xorw %bx,%bx /* bx is starting address within segment */
-rp_read:
- movw %es,%ax
- movw %bx,%dx
- movb $4, %cl
- shrw %cl,%dx /* bx is always divisible by 16 */
- addw %dx,%ax
- cmpw endseg, %ax /* have we loaded all yet? */
- jb ok1_read
- ret
-ok1_read:
- movw sectors, %ax
- subw sread, %ax
- movw %ax,%cx
- shlw $9, %cx
- addw %bx,%cx
- jnc ok2_read
- je ok2_read
- xorw %ax,%ax
- subw %bx,%ax
- shrw $9, %ax
-ok2_read:
- call read_track
- movw %ax,%cx
- addw sread, %ax
- cmpw sectors, %ax
- jne ok3_read
- movw $1, %ax
- subw head, %ax
- jne ok4_read
- incw track
-ok4_read:
- movw %ax, head
- xorw %ax,%ax
-ok3_read:
- movw %ax, sread
- shlw $9, %cx
- addw %cx,%bx
- jnc rp_read
- movw %es,%ax
- addb $0x10, %ah
- movw %ax,%es
- xorw %bx,%bx
- jmp rp_read
-
-read_track:
- pusha
- pushw %ax
- pushw %bx
- pushw %bp /* just in case the BIOS is buggy */
- movw $0x0e2e, %ax /* 0x2e = . */
- movw $0x0007, %bx
- int $0x10
- popw %bp
- popw %bx
- popw %ax
-
- movw track, %dx
- movw sread, %cx
- incw %cx
- movb %dl,%ch
- movw head, %dx
- movb %dl,%dh
- andw $0x0100, %dx
- movb $2, %ah
-
- pushw %dx /* save for error dump */
- pushw %cx
- pushw %bx
- pushw %ax
-
- int $0x13
- jc bad_rt
- addw $8, %sp
- popa
- ret
-
-bad_rt: pushw %ax /* save error code */
- call print_all /* ah = error, al = read */
-
- xorb %ah,%ah
- xorb %dl,%dl
- int $0x13
-
- addw $10, %sp
- popa
- jmp read_track
-
-/* print_all is for debugging purposes. It will print out all of the registers.
- * The assumption is that this is called from a routine, with a stack frame like
- * dx
- * cx
- * bx
- * ax
- * error
- * ret <- sp
- */
-
-print_all:
- call print_nl /* nl for readability */
- movw $5, %cx /* error code + 4 registers */
- movw %sp,%bp
-
-print_loop:
- pushw %cx /* save count left */
-
- cmpb $5, %cl
- jae no_reg /* see if register name is needed */
-
- movw $0x0007, %bx /* page 0, attribute 7 (normal) */
- movw $0xe05+0x41-1, %ax
- subb %cl,%al
- int $0x10
-
- movb $0x58, %al /* 'X' */
- int $0x10
-
- movb $0x3A, %al /* ':' */
- int $0x10
-
-no_reg:
- addw $2, %bp /* next register */
- call print_hex /* print it */
- movb $0x20, %al /* print a space */
- int $0x10
- popw %cx
- loop print_loop
- call print_nl /* nl for readability */
- ret
-
-print_str:
- movw $0x0007, %bx /* page 0, attribute 7 (normal) */
- movb $0x0e, %ah /* write char, tty mode */
-prloop:
- lodsb
- int $0x10
- loop prloop
- ret
-
-print_nl:
- movw $0x0007, %bx /* page 0, attribute 7 (normal) */
- movw $0xe0d, %ax /* CR */
- int $0x10
- movb $0xa, %al /* LF */
- int $0x10
- ret
-
-/* print_hex prints the word pointed to by ss:bp in hexadecimal. */
-
-print_hex:
- movw (%bp),%dx /* load word into dx */
- movb $4, %cl
- movb $0x0e, %ah /* write char, tty mode */
- movw $0x0007, %bx /* page 0, attribute 7 (normal) */
- call print_digit
- call print_digit
- call print_digit
-/* fall through */
-print_digit:
- rol %cl,%dx /* rotate so that lowest 4 bits are used */
- movb $0x0f, %al /* mask for nybble */
- andb %dl,%al
- addb $0x90, %al /* convert al to ascii hex (four instructions) */
- daa
- adcb $0x40, %al
- daa
- int $0x10
- ret
-
-sread: .word 0 /* sectors read of current track */
-head: .word 0 /* current head */
-track: .word 0 /* current track */
-
-sectors:
- .word 0
-
-dpseg: .word 0
-dpoff: .word 0
-
-disksizes:
- .byte 36,18,15,9
-
-msg1:
- .ascii "Loading ROM image"
-msg1end:
-
- .org 510, 0
- .word 0xAA55
-
-start_runtime:
- /* Install gPXE */
- call install
-
- /* Set up real-mode stack */
- movw %bx, %ss
- movw $_estack16, %sp
-
- /* Jump to .text16 segment */
- pushw %ax
- pushw $1f
- lret
- .section ".text16", "awx", @progbits
-1:
- pushl $main
- pushw %cs
- call prot_call
- popl %ecx /* discard */
-
- /* Uninstall gPXE */
- call uninstall
-
- /* Boot next device */
- int $0x18
-
diff --git a/gpxe/src/arch/i386/prefix/hdprefix.S b/gpxe/src/arch/i386/prefix/hdprefix.S
deleted file mode 100644
index 05767567..00000000
--- a/gpxe/src/arch/i386/prefix/hdprefix.S
+++ /dev/null
@@ -1,109 +0,0 @@
-FILE_LICENCE ( GPL2_OR_LATER )
-
- .text
- .arch i386
- .section ".prefix", "awx", @progbits
- .code16
- .org 0
-
- movw $load_image, %bp
- jmp find_active_partition
-
-#include "bootpart.S"
-
-load_image:
- /* Get disk geometry */
- pushal
- pushw %es
- movb $0x08, %ah
- int $0x13
- jc load_failed
- movb %cl, max_sector
- movb %dh, max_head
- popw %es
- popal
-
-1: /* Read to end of current track */
- movb %cl, %al
- negb %al
- addb max_sector, %al
- incb %al
- andb $0x3f, %al
- movzbl %al, %eax
- call *read_sectors
- jc load_failed
-
- /* Update %es */
- movw %es, %bx
- shll $5, %eax
- addw %ax, %bx
- movw %bx, %es
- shrl $5, %eax
-
- /* Update LBA address */
- addl %eax, %edi
- adcl $0, %esi
-
- /* Update CHS address */
- andb $0xc0, %cl
- orb $0x01, %cl
- incb %dh
- cmpb max_head, %dh
- jbe 2f
- xorb %dh, %dh
- incb %ch
- jnc 2f
- addb $0xc0, %cl
-2:
- /* Loop until whole image is read */
- subl %eax, load_length
- ja 1b
- ljmp $BOOT_SEG, $start_image
-
-max_sector:
- .byte 0
-max_head:
- .byte 0
-load_length:
- .long 0
-
- .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
- .ascii "ADDL"
- .long load_length
- .long 512
- .long 0
- .previous
-
-
-load_failed:
- movw $10f, %si
- jmp boot_error
-10: .asciz "Could not load gPXE\r\n"
-
- .org 510
- .byte 0x55, 0xaa
-
-start_image:
- /* Install gPXE */
- call install
-
- /* Set up real-mode stack */
- movw %bx, %ss
- movw $_estack16, %sp
-
- /* Jump to .text16 segment */
- pushw %ax
- pushw $1f
- lret
- .section ".text16", "awx", @progbits
-1:
- pushl $main
- pushw %cs
- call prot_call
- popl %ecx /* discard */
-
- /* Uninstall gPXE */
- call uninstall
-
- /* Boot next device */
- int $0x18
diff --git a/gpxe/src/arch/i386/prefix/hromprefix.S b/gpxe/src/arch/i386/prefix/hromprefix.S
deleted file mode 100644
index 03acf1e2..00000000
--- a/gpxe/src/arch/i386/prefix/hromprefix.S
+++ /dev/null
@@ -1,12 +0,0 @@
-/*****************************************************************************
- * ROM prefix that relocates to HIGHMEM_LOADPOINT during POST if PMM allocation
- * fails. Intended to be used, with caution, on BIOSes that support PCI3.00 but
- * have limited PMM support, such as most AMI BIOSes.
- *****************************************************************************
- */
-
-FILE_LICENCE ( GPL2_OR_LATER )
-
-#define SHRINK_WITHOUT_PMM
-
-#include "romprefix.S"
diff --git a/gpxe/src/arch/i386/prefix/kkpxeprefix.S b/gpxe/src/arch/i386/prefix/kkpxeprefix.S
deleted file mode 100644
index 02cc6fee..00000000
--- a/gpxe/src/arch/i386/prefix/kkpxeprefix.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/*****************************************************************************
- * PXE prefix that keeps the whole PXE stack present
- *****************************************************************************
- */
-
-FILE_LICENCE ( GPL2_OR_LATER )
-
-/* Since we have the whole stack, we can use cached DHCP information */
-REQUEST_OBJECT ( pxeparent_dhcp )
-
-#define PXELOADER_KEEP_UNDI
-#define PXELOADER_KEEP_PXE
-#include "pxeprefix.S"
diff --git a/gpxe/src/arch/i386/prefix/kpxeprefix.S b/gpxe/src/arch/i386/prefix/kpxeprefix.S
deleted file mode 100644
index 923faccc..00000000
--- a/gpxe/src/arch/i386/prefix/kpxeprefix.S
+++ /dev/null
@@ -1,9 +0,0 @@
-/*****************************************************************************
- * PXE prefix that keep the UNDI portion of the PXE stack present
- *****************************************************************************
- */
-
-FILE_LICENCE ( GPL2_OR_LATER )
-
-#define PXELOADER_KEEP_UNDI
-#include "pxeprefix.S"
diff --git a/gpxe/src/arch/i386/prefix/libprefix.S b/gpxe/src/arch/i386/prefix/libprefix.S
deleted file mode 100644
index 9e6ba6f0..00000000
--- a/gpxe/src/arch/i386/prefix/libprefix.S
+++ /dev/null
@@ -1,819 +0,0 @@
-/*
- * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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.
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER )
-
- .arch i386
-
-/**
- * High memory temporary load address
- *
- * Temporary buffer into which to copy (or decompress) our runtime
- * image, prior to calling get_memmap() and relocate(). We don't
- * actually leave anything here once install() has returned.
- *
- * We use the start of an even megabyte so that we don't have to worry
- * about the current state of the A20 line.
- *
- * We use 4MB rather than 2MB because some PXE stack / PMM BIOS
- * combinations are known to place data required by other UNDI ROMs
- * loader around the 2MB mark.
- */
- .globl HIGHMEM_LOADPOINT
- .equ HIGHMEM_LOADPOINT, ( 4 << 20 )
-
-/* Image compression enabled */
-#define COMPRESS 1
-
-#define CR0_PE 1
-
-/*****************************************************************************
- * Utility function: print character (with LF -> LF,CR translation)
- *
- * Parameters:
- * %al : character to print
- * %ds:di : output buffer (or %di=0 to print to console)
- * Returns:
- * %ds:di : next character in output buffer (if applicable)
- *****************************************************************************
- */
- .section ".prefix.lib", "awx", @progbits
- .code16
- .globl print_character
-print_character:
- /* Preserve registers */
- pushw %ax
- pushw %bx
- pushw %bp
- /* If %di is non-zero, write character to buffer and exit */
- testw %di, %di
- jz 1f
- movb %al, %ds:(%di)
- incw %di
- jmp 3f
-1: /* Print character */
- movw $0x0007, %bx /* page 0, attribute 7 (normal) */
- movb $0x0e, %ah /* write char, tty mode */
- cmpb $0x0a, %al /* '\n'? */
- jne 2f
- int $0x10
- movb $0x0d, %al
-2: int $0x10
- /* Restore registers and return */
-3: popw %bp
- popw %bx
- popw %ax
- ret
- .size print_character, . - print_character
-
-/*****************************************************************************
- * Utility function: print a NUL-terminated string
- *
- * Parameters:
- * %ds:si : string to print
- * %ds:di : output buffer (or %di=0 to print to console)
- * Returns:
- * %ds:si : character after terminating NUL
- * %ds:di : next character in output buffer (if applicable)
- *****************************************************************************
- */
- .section ".prefix.lib", "awx", @progbits
- .code16
- .globl print_message
-print_message:
- /* Preserve registers */
- pushw %ax
- /* Print string */
-1: lodsb
- testb %al, %al
- je 2f
- call print_character
- jmp 1b
-2: /* Restore registers and return */
- popw %ax
- ret
- .size print_message, . - print_message
-
-/*****************************************************************************
- * Utility functions: print hex digit/byte/word/dword
- *
- * Parameters:
- * %al (low nibble) : digit to print
- * %al : byte to print
- * %ax : word to print
- * %eax : dword to print
- * %ds:di : output buffer (or %di=0 to print to console)
- * Returns:
- * %ds:di : next character in output buffer (if applicable)
- *****************************************************************************
- */
- .section ".prefix.lib", "awx", @progbits
- .code16
- .globl print_hex_dword
-print_hex_dword:
- rorl $16, %eax
- call print_hex_word
- rorl $16, %eax
- /* Fall through */
- .size print_hex_dword, . - print_hex_dword
- .globl print_hex_word
-print_hex_word:
- xchgb %al, %ah
- call print_hex_byte
- xchgb %al, %ah
- /* Fall through */
- .size print_hex_word, . - print_hex_word
- .globl print_hex_byte
-print_hex_byte:
- rorb $4, %al
- call print_hex_nibble
- rorb $4, %al
- /* Fall through */
- .size print_hex_byte, . - print_hex_byte
- .globl print_hex_nibble
-print_hex_nibble:
- /* Preserve registers */
- pushw %ax
- /* Print digit (technique by Norbert Juffa <norbert.juffa@amd.com> */
- andb $0x0f, %al
- cmpb $10, %al
- sbbb $0x69, %al
- das
- call print_character
- /* Restore registers and return */
- popw %ax
- ret
- .size print_hex_nibble, . - print_hex_nibble
-
-/*****************************************************************************
- * Utility function: print PCI bus:dev.fn
- *
- * Parameters:
- * %ax : PCI bus:dev.fn to print
- * %ds:di : output buffer (or %di=0 to print to console)
- * Returns:
- * %ds:di : next character in output buffer (if applicable)
- *****************************************************************************
- */
- .section ".prefix.lib", "awx", @progbits
- .code16
- .globl print_pci_busdevfn
-print_pci_busdevfn:
- /* Preserve registers */
- pushw %ax
- /* Print bus */
- xchgb %al, %ah
- call print_hex_byte
- /* Print ":" */
- movb $( ':' ), %al
- call print_character
- /* Print device */
- movb %ah, %al
- shrb $3, %al
- call print_hex_byte
- /* Print "." */
- movb $( '.' ), %al
- call print_character
- /* Print function */
- movb %ah, %al
- andb $0x07, %al
- call print_hex_nibble
- /* Restore registers and return */
- popw %ax
- ret
- .size print_pci_busdevfn, . - print_pci_busdevfn
-
-/*****************************************************************************
- * Utility function: clear current line
- *
- * Parameters:
- * %ds:di : output buffer (or %di=0 to print to console)
- * Returns:
- * %ds:di : next character in output buffer (if applicable)
- *****************************************************************************
- */
- .section ".prefix.lib", "awx", @progbits
- .code16
- .globl print_kill_line
-print_kill_line:
- /* Preserve registers */
- pushw %ax
- pushw %cx
- /* Print CR */
- movb $( '\r' ), %al
- call print_character
- /* Print 79 spaces */
- movb $( ' ' ), %al
- movw $79, %cx
-1: call print_character
- loop 1b
- /* Print CR */
- movb $( '\r' ), %al
- call print_character
- /* Restore registers and return */
- popw %cx
- popw %ax
- ret
- .size print_kill_line, . - print_kill_line
-
-/****************************************************************************
- * pm_call (real-mode near call)
- *
- * Call routine in 16-bit protected mode for access to extended memory
- *
- * Parameters:
- * %ax : address of routine to call in 16-bit protected mode
- * Returns:
- * none
- * Corrupts:
- * %ax
- *
- * The specified routine is called in 16-bit protected mode, with:
- *
- * %cs : 16-bit code segment with base matching real-mode %cs
- * %ss : 16-bit data segment with base matching real-mode %ss
- * %ds,%es,%fs,%gs : 32-bit data segment with zero base and 4GB limit
- *
- ****************************************************************************
- */
-
-#ifndef KEEP_IT_REAL
-
- /* GDT for protected-mode calls */
- .section ".prefix.lib", "awx", @progbits
- .align 16
-pm_call_vars:
-gdt:
-gdt_limit: .word gdt_length - 1
-gdt_base: .long 0
- .word 0 /* padding */
-pm_cs: /* 16-bit protected-mode code segment */
- .equ PM_CS, pm_cs - gdt
- .word 0xffff, 0
- .byte 0, 0x9b, 0x00, 0
-pm_ss: /* 16-bit protected-mode stack segment */
- .equ PM_SS, pm_ss - gdt
- .word 0xffff, 0
- .byte 0, 0x93, 0x00, 0
-pm_ds: /* 32-bit protected-mode flat data segment */
- .equ PM_DS, pm_ds - gdt
- .word 0xffff, 0
- .byte 0, 0x93, 0xcf, 0
-gdt_end:
- .equ gdt_length, . - gdt
- .size gdt, . - gdt
-
- .section ".prefix.lib", "awx", @progbits
- .align 16
-pm_saved_gdt:
- .long 0, 0
- .size pm_saved_gdt, . - pm_saved_gdt
-
- .equ pm_call_vars_size, . - pm_call_vars
-#define PM_CALL_VAR(x) ( -pm_call_vars_size + ( (x) - pm_call_vars ) )
-
- .section ".prefix.lib", "awx", @progbits
- .code16
-pm_call:
- /* Preserve registers, flags, and RM return point */
- pushw %bp
- movw %sp, %bp
- subw $pm_call_vars_size, %sp
- andw $0xfff0, %sp
- pushfl
- pushw %gs
- pushw %fs
- pushw %es
- pushw %ds
- pushw %ss
- pushw %cs
- pushw $99f
-
- /* Set up local variable block, and preserve GDT */
- pushw %cx
- pushw %si
- pushw %di
- pushw %ss
- popw %es
- movw $pm_call_vars, %si
- leaw PM_CALL_VAR(pm_call_vars)(%bp), %di
- movw $pm_call_vars_size, %cx
- cs rep movsb
- popw %di
- popw %si
- popw %cx
- sgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
-
- /* Set up GDT bases */
- pushl %eax
- pushl %edi
- xorl %eax, %eax
- movw %ss, %ax
- shll $4, %eax
- movzwl %bp, %edi
- addr32 leal PM_CALL_VAR(gdt)(%eax, %edi), %eax
- movl %eax, PM_CALL_VAR(gdt_base)(%bp)
- movw %cs, %ax
- movw $PM_CALL_VAR(pm_cs), %di
- call set_seg_base
- movw %ss, %ax
- movw $PM_CALL_VAR(pm_ss), %di
- call set_seg_base
- popl %edi
- popl %eax
-
- /* Switch CPU to protected mode and load up segment registers */
- pushl %eax
- cli
- data32 lgdt PM_CALL_VAR(gdt)(%bp)
- movl %cr0, %eax
- orb $CR0_PE, %al
- movl %eax, %cr0
- ljmp $PM_CS, $1f
-1: movw $PM_SS, %ax
- movw %ax, %ss
- movw $PM_DS, %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
- popl %eax
-
- /* Call PM routine */
- call *%ax
-
- /* Set real-mode segment limits on %ds, %es, %fs and %gs */
- movw %ss, %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
-
- /* Return CPU to real mode */
- movl %cr0, %eax
- andb $0!CR0_PE, %al
- movl %eax, %cr0
-
- /* Restore registers and flags */
- lret /* will ljmp to 99f */
-99: popw %ss
- popw %ds
- popw %es
- popw %fs
- popw %gs
- data32 lgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
- popfl
- movw %bp, %sp
- popw %bp
- ret
- .size pm_call, . - pm_call
-
-set_seg_base:
- rolw $4, %ax
- movw %ax, 2(%bp,%di)
- andw $0xfff0, 2(%bp,%di)
- movb %al, 4(%bp,%di)
- andb $0x0f, 4(%bp,%di)
- ret
- .size set_seg_base, . - set_seg_base
-
-#endif /* KEEP_IT_REAL */
-
-/****************************************************************************
- * copy_bytes (real-mode or 16-bit protected-mode near call)
- *
- * Copy bytes
- *
- * Parameters:
- * %ds:esi : source address
- * %es:edi : destination address
- * %ecx : length
- * Returns:
- * %ds:esi : next source address
- * %es:edi : next destination address
- * Corrupts:
- * None
- ****************************************************************************
- */
- .section ".prefix.lib", "awx", @progbits
- .code16
-copy_bytes:
- pushl %ecx
- rep addr32 movsb
- popl %ecx
- ret
- .size copy_bytes, . - copy_bytes
-
-/****************************************************************************
- * install_block (real-mode near call)
- *
- * Install block to specified address
- *
- * Parameters:
- * %esi : source physical address (must be a multiple of 16)
- * %edi : destination physical address (must be a multiple of 16)
- * %ecx : length of (decompressed) data
- * %edx : total length of block (including any uninitialised data portion)
- * Returns:
- * %esi : next source physical address (will be a multiple of 16)
- * Corrupts:
- * none
- ****************************************************************************
- */
- .section ".prefix.lib", "awx", @progbits
- .code16
-install_block:
-
-#ifdef KEEP_IT_REAL
-
- /* Preserve registers */
- pushw %ds
- pushw %es
- pushl %ecx
- pushl %edi
-
- /* Convert %esi and %edi to segment registers */
- shrl $4, %esi
- movw %si, %ds
- xorw %si, %si
- shrl $4, %edi
- movw %di, %es
- xorw %di, %di
-
-#else /* KEEP_IT_REAL */
-
- /* Call self in protected mode */
- pushw %ax
- movw $1f, %ax
- call pm_call
- popw %ax
- ret
-1:
- /* Preserve registers */
- pushl %ecx
- pushl %edi
-
-#endif /* KEEP_IT_REAL */
-
-
-#if COMPRESS
- /* Decompress source to destination */
- call decompress16
-#else
- /* Copy source to destination */
- call copy_bytes
-#endif
-
- /* Zero .bss portion */
- negl %ecx
- addl %edx, %ecx
- pushw %ax
- xorw %ax, %ax
- rep addr32 stosb
- popw %ax
-
- /* Round up %esi to start of next source block */
- addl $0xf, %esi
- andl $~0xf, %esi
-
-
-#ifdef KEEP_IT_REAL
-
- /* Convert %ds:esi back to a physical address */
- movzwl %ds, %cx
- shll $4, %ecx
- addl %ecx, %esi
-
- /* Restore registers */
- popl %edi
- popl %ecx
- popw %es
- popw %ds
-
-#else /* KEEP_IT_REAL */
-
- /* Restore registers */
- popl %edi
- popl %ecx
-
-#endif
-
- ret
- .size install_block, . - install_block
-
-/****************************************************************************
- * alloc_basemem (real-mode near call)
- *
- * Allocate space for .text16 and .data16 from top of base memory.
- * Memory is allocated using the BIOS free base memory counter at
- * 0x40:13.
- *
- * Parameters:
- * none
- * Returns:
- * %ax : .text16 segment address
- * %bx : .data16 segment address
- * Corrupts:
- * none
- ****************************************************************************
- */
- .section ".prefix.lib", "awx", @progbits
- .code16
- .globl alloc_basemem
-alloc_basemem:
- /* Preserve registers */
- pushw %fs
-
- /* FBMS => %ax as segment address */
- pushw $0x40
- popw %fs
- movw %fs:0x13, %ax
- shlw $6, %ax
-
- /* Calculate .data16 segment address */
- subw $_data16_memsz_pgh, %ax
- pushw %ax
-
- /* Calculate .text16 segment address */
- subw $_text16_memsz_pgh, %ax
- pushw %ax
-
- /* Update FBMS */
- shrw $6, %ax
- movw %ax, %fs:0x13
-
- /* Retrieve .text16 and .data16 segment addresses */
- popw %ax
- popw %bx
-
- /* Restore registers and return */
- popw %fs
- ret
- .size alloc_basemem, . - alloc_basemem
-
-/****************************************************************************
- * free_basemem (real-mode near call)
- *
- * Free space allocated with alloc_basemem.
- *
- * Parameters:
- * %ax : .text16 segment address
- * %bx : .data16 segment address
- * Returns:
- * %ax : 0 if successfully freed
- * Corrupts:
- * none
- ****************************************************************************
- */
- .section ".text16", "ax", @progbits
- .code16
- .globl free_basemem
-free_basemem:
- /* Preserve registers */
- pushw %fs
-
- /* Check FBMS counter */
- pushw %ax
- shrw $6, %ax
- pushw $0x40
- popw %fs
- cmpw %ax, %fs:0x13
- popw %ax
- jne 1f
-
- /* Check hooked interrupt count */
- cmpw $0, %cs:hooked_bios_interrupts
- jne 1f
-
- /* OK to free memory */
- addw $_text16_memsz_pgh, %ax
- addw $_data16_memsz_pgh, %ax
- shrw $6, %ax
- movw %ax, %fs:0x13
- xorw %ax, %ax
-
-1: /* Restore registers and return */
- popw %fs
- ret
- .size free_basemem, . - free_basemem
-
- .section ".text16.data", "aw", @progbits
- .globl hooked_bios_interrupts
-hooked_bios_interrupts:
- .word 0
- .size hooked_bios_interrupts, . - hooked_bios_interrupts
-
-/****************************************************************************
- * install (real-mode near call)
- *
- * Install all text and data segments.
- *
- * Parameters:
- * none
- * Returns:
- * %ax : .text16 segment address
- * %bx : .data16 segment address
- * Corrupts:
- * none
- ****************************************************************************
- */
- .section ".prefix.lib", "awx", @progbits
- .code16
- .globl install
-install:
- /* Preserve registers */
- pushl %esi
- pushl %edi
- /* Allocate space for .text16 and .data16 */
- call alloc_basemem
- /* Image source = %cs:0000 */
- xorl %esi, %esi
- /* Image destination = HIGHMEM_LOADPOINT */
- movl $HIGHMEM_LOADPOINT, %edi
- /* Install text and data segments */
- call install_prealloc
- /* Restore registers and return */
- popl %edi
- popl %esi
- ret
- .size install, . - install
-
-/****************************************************************************
- * install_prealloc (real-mode near call)
- *
- * Install all text and data segments.
- *
- * Parameters:
- * %ax : .text16 segment address
- * %bx : .data16 segment address
- * %esi : Image source physical address (or zero for %cs:0000)
- * %edi : Decompression temporary area physical address
- * Corrupts:
- * none
- ****************************************************************************
- */
- .section ".prefix.lib", "awx", @progbits
- .code16
- .globl install_prealloc
-install_prealloc:
- /* Save registers */
- pushal
- pushw %ds
- pushw %es
-
- /* Sanity: clear the direction flag asap */
- cld
-
- /* Calculate physical address of payload (i.e. first source) */
- testl %esi, %esi
- jnz 1f
- movw %cs, %si
- shll $4, %esi
-1: addl $_payload_lma, %esi
-
- /* Install .text16 and .data16 */
- pushl %edi
- movzwl %ax, %edi
- shll $4, %edi
- movl $_text16_memsz, %ecx
- movl %ecx, %edx
- call install_block /* .text16 */
- movzwl %bx, %edi
- shll $4, %edi
- movl $_data16_filesz, %ecx
- movl $_data16_memsz, %edx
- call install_block /* .data16 */
- popl %edi
-
- /* Set up %ds for access to .data16 */
- movw %bx, %ds
-
-#ifdef KEEP_IT_REAL
- /* Initialise libkir */
- movw %ax, (init_libkir_vector+2)
- lcall *init_libkir_vector
-#else
- /* Install .text and .data to temporary area in high memory,
- * prior to reading the E820 memory map and relocating
- * properly.
- */
- movl $_textdata_filesz, %ecx
- movl $_textdata_memsz, %edx
- call install_block
-
- /* Initialise librm at current location */
- movw %ax, (init_librm_vector+2)
- lcall *init_librm_vector
-
- /* Call relocate() to determine target address for relocation.
- * relocate() will return with %esi, %edi and %ecx set up
- * ready for the copy to the new location.
- */
- movw %ax, (prot_call_vector+2)
- pushl $relocate
- lcall *prot_call_vector
- popl %edx /* discard */
-
- /* Copy code to new location */
- pushl %edi
- pushw %ax
- movw $copy_bytes, %ax
- call pm_call
- popw %ax
- popl %edi
-
- /* Initialise librm at new location */
- lcall *init_librm_vector
-
-#endif
- /* Restore registers */
- popw %es
- popw %ds
- popal
- ret
- .size install_prealloc, . - install_prealloc
-
- /* Vectors for far calls to .text16 functions */
- .section ".data16", "aw", @progbits
-#ifdef KEEP_IT_REAL
-init_libkir_vector:
- .word init_libkir
- .word 0
- .size init_libkir_vector, . - init_libkir_vector
-#else
-init_librm_vector:
- .word init_librm
- .word 0
- .size init_librm_vector, . - init_librm_vector
-prot_call_vector:
- .word prot_call
- .word 0
- .size prot_call_vector, . - prot_call_vector
-#endif
-
-/****************************************************************************
- * uninstall (real-mode near call)
- *
- * Uninstall all text and data segments.
- *
- * Parameters:
- * %ax : .text16 segment address
- * %bx : .data16 segment address
- * Returns:
- * none
- * Corrupts:
- * none
- ****************************************************************************
- */
- .section ".text16", "ax", @progbits
- .code16
- .globl uninstall
-uninstall:
- call free_basemem
- ret
- .size uninstall, . - uninstall
-
-
-
- /* File split information for the compressor */
-#if COMPRESS
- .section ".zinfo", "a", @progbits
- .ascii "COPY"
- .long _prefix_lma
- .long _prefix_filesz
- .long _max_align
- .ascii "PACK"
- .long _text16_lma
- .long _text16_filesz
- .long _max_align
- .ascii "PACK"
- .long _data16_lma
- .long _data16_filesz
- .long _max_align
- .ascii "PACK"
- .long _textdata_lma
- .long _textdata_filesz
- .long _max_align
-#else /* COMPRESS */
- .section ".zinfo", "a", @progbits
- .ascii "COPY"
- .long _prefix_lma
- .long _filesz
- .long _max_align
-#endif /* COMPRESS */
diff --git a/gpxe/src/arch/i386/prefix/lkrnprefix.S b/gpxe/src/arch/i386/prefix/lkrnprefix.S
deleted file mode 100644
index 101d0388..00000000
--- a/gpxe/src/arch/i386/prefix/lkrnprefix.S
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- Copyright (C) 2000, Entity Cyber, Inc.
-
- Authors: Gary Byers (gb@thinguin.org)
- Marty Connor (mdc@thinguin.org)
-
- This software may be used and distributed according to the terms
- of the GNU Public License (GPL), incorporated herein by reference.
-
- Description:
-
- This is just a little bit of code and data that can get prepended
- to a ROM image in order to allow bootloaders to load the result
- as if it were a Linux kernel image.
-
- A real Linux kernel image consists of a one-sector boot loader
- (to load the image from a floppy disk), followed a few sectors
- of setup code, followed by the kernel code itself. There's
- a table in the first sector (starting at offset 497) that indicates
- how many sectors of setup code follow the first sector and which
- contains some other parameters that aren't interesting in this
- case.
-
- When a bootloader loads the sectors that comprise a kernel image,
- it doesn't execute the code in the first sector (since that code
- would try to load the image from a floppy disk.) The code in the
- first sector below doesn't expect to get executed (and prints an
- error message if it ever -is- executed.)
-
- We don't require much in the way of setup code. Historically, the
- Linux kernel required at least 4 sectors of setup code.
- Therefore, at least 4 sectors must be present even though we don't
- use them.
-
-*/
-
-FILE_LICENCE ( GPL_ANY )
-
-#define SETUPSECS 4 /* Minimal nr of setup-sectors */
-#define PREFIXSIZE ((SETUPSECS+1)*512)
-#define PREFIXPGH (PREFIXSIZE / 16 )
-#define BOOTSEG 0x07C0 /* original address of boot-sector */
-#define INITSEG 0x9000 /* we move boot here - out of the way */
-#define SETUPSEG 0x9020 /* setup starts here */
-#define SYSSEG 0x1000 /* system loaded at 0x10000 (65536). */
-
- .text
- .code16
- .arch i386
- .org 0
- .section ".prefix", "ax", @progbits
-/*
- This is a minimal boot sector. If anyone tries to execute it (e.g., if
- a .lilo file is dd'ed to a floppy), print an error message.
-*/
-
-bootsector:
- jmp $BOOTSEG, $1f /* reload cs:ip to match relocation addr */
-1:
- movw $0x2000, %di /* 0x2000 is arbitrary value >= length
- of bootsect + room for stack */
-
- movw $BOOTSEG, %ax
- movw %ax,%ds
- movw %ax,%es
-
- cli
- movw %ax, %ss /* put stack at BOOTSEG:0x2000. */
- movw %di,%sp
- sti
-
- movw $why_end-why, %cx
- movw $why, %si
-
- movw $0x0007, %bx /* page 0, attribute 7 (normal) */
- movb $0x0e, %ah /* write char, tty mode */
-prloop:
- lodsb
- int $0x10
- loop prloop
-freeze: jmp freeze
-
-why: .ascii "This image cannot be loaded from a floppy disk.\r\n"
-why_end:
-
-
-/*
- The following header is documented in the Linux source code at
- Documentation/i386/boot.txt
-*/
- .org 497
-setup_sects:
- .byte SETUPSECS
-root_flags:
- .word 0
-syssize:
- .long -PREFIXPGH
-
- .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
- .ascii "ADDL"
- .long syssize
- .long 16
- .long 0
- .previous
-
-ram_size:
- .word 0
-vid_mode:
- .word 0
-root_dev:
- .word 0
-boot_flag:
- .word 0xAA55
-jump:
- /* Manually specify a two-byte jmp instruction here rather
- * than leaving it up to the assembler. */
- .byte 0xeb
- .byte setup_code - header
-header:
- .byte 'H', 'd', 'r', 'S'
-version:
- .word 0x0207 /* 2.07 */
-realmode_swtch:
- .long 0
-start_sys:
- .word 0
-kernel_version:
- .word 0
-type_of_loader:
- .byte 0
-loadflags:
- .byte 0
-setup_move_size:
- .word 0
-code32_start:
- .long 0
-ramdisk_image:
- .long 0
-ramdisk_size:
- .long 0
-bootsect_kludge:
- .long 0
-heap_end_ptr:
- .word 0
-pad1:
- .word 0
-cmd_line_ptr:
- .long 0
-initrd_addr_max:
- /* We don't use an initrd but some bootloaders (e.g. SYSLINUX) have
- * been known to require this field. Set the value to 2 GB. This
- * value is also used by the Linux kernel. */
- .long 0x7fffffff
-kernel_alignment:
- .long 0
-relocatable_kernel:
- .byte 0
-pad2:
- .byte 0, 0, 0
-cmdline_size:
- .long 0
-hardware_subarch:
- .long 0
-hardware_subarch_data:
- .byte 0, 0, 0, 0, 0, 0, 0, 0
-
-/*
- We don't need to do too much setup.
-
- This code gets loaded at SETUPSEG:0. It wants to start
- executing the image that's loaded at SYSSEG:0 and
- whose entry point is SYSSEG:0.
-*/
-setup_code:
- /* We expect to be contiguous in memory once loaded. The Linux image
- * boot process requires that setup code is loaded separately from
- * "non-real code". Since we don't need any information that's left
- * in the prefix, it doesn't matter: we just have to ensure that
- * %cs:0000 is where the start of the image *would* be.
- */
- ljmp $(SYSSEG-(PREFIXSIZE/16)), $run_gpxe
-
-
- .org PREFIXSIZE
-/*
- We're now at the beginning of the kernel proper.
- */
-run_gpxe:
- /* Set up stack just below 0x7c00 */
- xorw %ax, %ax
- movw %ax, %ss
- movw $0x7c00, %sp
-
- /* Install gPXE */
- call install
-
- /* Set up real-mode stack */
- movw %bx, %ss
- movw $_estack16, %sp
-
- /* Jump to .text16 segment */
- pushw %ax
- pushw $1f
- lret
- .section ".text16", "awx", @progbits
-1:
- pushl $main
- pushw %cs
- call prot_call
- popl %ecx /* discard */
-
- /* Uninstall gPXE */
- call uninstall
-
- /* Boot next device */
- int $0x18
diff --git a/gpxe/src/arch/i386/prefix/mbr.S b/gpxe/src/arch/i386/prefix/mbr.S
deleted file mode 100644
index adfe2041..00000000
--- a/gpxe/src/arch/i386/prefix/mbr.S
+++ /dev/null
@@ -1,13 +0,0 @@
- .text
- .arch i386
- .section ".prefix", "awx", @progbits
- .code16
- .org 0
-
-mbr:
- movw $exec_sector, %bp
- jmp find_active_partition
-exec_sector:
- ljmp $0x0000, $0x7c00
-
-#include "bootpart.S"
diff --git a/gpxe/src/arch/i386/prefix/nbiprefix.S b/gpxe/src/arch/i386/prefix/nbiprefix.S
deleted file mode 100644
index 607d80fb..00000000
--- a/gpxe/src/arch/i386/prefix/nbiprefix.S
+++ /dev/null
@@ -1,77 +0,0 @@
- .text
- .arch i386
- .code16
- .section ".prefix", "ax", @progbits
- .org 0
-
-nbi_header:
-
-/*****************************************************************************
- * NBI file header
- *****************************************************************************
- */
-file_header:
- .long 0x1b031336 /* Signature */
- .byte 0x04 /* 16 bytes header, no vendor info */
- .byte 0
- .byte 0
- .byte 0 /* No flags */
- .word 0x0000, 0x07c0 /* Load header to 0x07c0:0x0000 */
- .word entry, 0x07c0 /* Start execution at 0x07c0:entry */
- .size file_header, . - file_header
-
-/*****************************************************************************
- * NBI segment header
- *****************************************************************************
- */
-segment_header:
- .byte 0x04 /* 16 bytes header, no vendor info */
- .byte 0
- .byte 0
- .byte 0x04 /* Last segment */
- .long 0x00007e00
-imglen: .long -512
-memlen: .long -512
- .size segment_header, . - segment_header
-
- .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
- .ascii "ADDL"
- .long imglen
- .long 1
- .long 0
- .ascii "ADDL"
- .long memlen
- .long 1
- .long 0
- .previous
-
-/*****************************************************************************
- * NBI entry point
- *****************************************************************************
- */
-entry:
- /* Install gPXE */
- call install
-
- /* Jump to .text16 segment */
- pushw %ax
- pushw $1f
- lret
- .section ".text16", "awx", @progbits
-1:
- pushl $main
- pushw %cs
- call prot_call
- popl %ecx /* discard */
-
- /* Uninstall gPXE */
- call uninstall
-
- /* Reboot system */
- int $0x19
-
- .previous
- .size entry, . - entry
-
-nbi_header_end:
- .org 512
diff --git a/gpxe/src/arch/i386/prefix/nullprefix.S b/gpxe/src/arch/i386/prefix/nullprefix.S
deleted file mode 100644
index 032d41e0..00000000
--- a/gpxe/src/arch/i386/prefix/nullprefix.S
+++ /dev/null
@@ -1,13 +0,0 @@
- .org 0
- .text
- .arch i386
-
- .section ".prefix", "ax", @progbits
- .code16
-_prefix:
-
- .section ".text16", "ax", @progbits
-prefix_exit:
-
-prefix_exit_end:
- .previous
diff --git a/gpxe/src/arch/i386/prefix/pxeprefix.S b/gpxe/src/arch/i386/prefix/pxeprefix.S
deleted file mode 100644
index e728c482..00000000
--- a/gpxe/src/arch/i386/prefix/pxeprefix.S
+++ /dev/null
@@ -1,761 +0,0 @@
-FILE_LICENCE ( GPL2_OR_LATER )
-
-#define PXENV_UNDI_SHUTDOWN 0x0005
-#define PXENV_UNDI_GET_NIC_TYPE 0x0012
-#define PXENV_UNDI_GET_IFACE_INFO 0x0013
-#define PXENV_STOP_UNDI 0x0015
-#define PXENV_UNLOAD_STACK 0x0070
-
-#define PXE_HACK_EB54 0x0001
-
- .text
- .arch i386
- .org 0
- .code16
-
-#include <undi.h>
-
-#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
-#define EB_MAGIC_1 ( 'E' + ( 't' << 8 ) + ( 'h' << 16 ) + ( 'e' << 24 ) )
-#define EB_MAGIC_2 ( 'r' + ( 'b' << 8 ) + ( 'o' << 16 ) + ( 'o' << 24 ) )
-
-/*****************************************************************************
- * Entry point: set operating context, print welcome message
- *****************************************************************************
- */
- .section ".prefix", "ax", @progbits
- jmp $0x7c0, $1f
-1:
- /* Preserve registers for possible return to PXE */
- pushfl
- pushal
- pushw %gs
- pushw %fs
- pushw %es
- pushw %ds
-
- /* Store magic word on PXE stack and remember PXE %ss:esp */
- pushl $STACK_MAGIC
- movw %ss, %cs:pxe_ss
- movl %esp, %cs:pxe_esp
-
- /* Set up segments */
- movw %cs, %ax
- movw %ax, %ds
- movw $0x40, %ax /* BIOS data segment access */
- movw %ax, %fs
- /* Set up stack just below 0x7c00 */
- xorw %ax, %ax
- movw %ax, %ss
- movl $0x7c00, %esp
- /* Clear direction flag, for the sake of sanity */
- cld
- /* Print welcome message */
- movw $10f, %si
- xorw %di, %di
- call print_message
- .section ".prefix.data", "aw", @progbits
-10: .asciz "PXE->EB:"
- .previous
-
-/*****************************************************************************
- * Find us a usable !PXE or PXENV+ entry point
- *****************************************************************************
- */
-detect_pxe:
- /* Plan A: !PXE pointer from the stack */
- lgsl pxe_esp, %ebp /* %gs:%bp -> original stack */
- lesw %gs:52(%bp), %bx
- call is_valid_ppxe
- je have_ppxe
-
- /* Plan B: PXENV+ pointer from initial ES:BX */
- movw %gs:32(%bp),%bx
- movw %gs:8(%bp),%es
- call is_valid_pxenv
- je have_pxenv
-
- /* Plan C: PXENV+ structure via INT 1Ah */
- movw $0x5650, %ax
- int $0x1a
- jc 1f
- cmpw $0x564e, %ax
- jne 1f
- call is_valid_pxenv
- je have_pxenv
-1:
- /* Plan D: scan base memory for !PXE */
- call memory_scan_ppxe
- je have_ppxe
-
- /* Plan E: scan base memory for PXENV+ */
- call memory_scan_pxenv
- jne stack_not_found
-
-have_pxenv:
- movw %bx, pxenv_offset
- movw %es, pxenv_segment
-
- cmpw $0x201, %es:6(%bx) /* API version >= 2.01 */
- jb 1f
- cmpb $0x2c, %es:8(%bx) /* ... and structure long enough */
- jb 2f
-
- lesw %es:0x28(%bx), %bx /* Find !PXE from PXENV+ */
- call is_valid_ppxe
- je have_ppxe
-2:
- call memory_scan_ppxe /* We are *supposed* to have !PXE... */
- je have_ppxe
-1:
- lesw pxenv_segoff, %bx /* Nope, we're stuck with PXENV+ */
-
- /* Record entry point and UNDI segments */
- pushl %es:0x0a(%bx) /* Entry point */
- pushw %es:0x24(%bx) /* UNDI code segment */
- pushw %es:0x26(%bx) /* UNDI code size */
- pushw %es:0x20(%bx) /* UNDI data segment */
- pushw %es:0x22(%bx) /* UNDI data size */
-
- /* Print "PXENV+ at <address>" */
- movw $10f, %si
- jmp check_have_stack
- .section ".prefix.data", "aw", @progbits
-10: .asciz " PXENV+ at "
- .previous
-
-have_ppxe:
- movw %bx, ppxe_offset
- movw %es, ppxe_segment
-
- pushl %es:0x10(%bx) /* Entry point */
- pushw %es:0x30(%bx) /* UNDI code segment */
- pushw %es:0x36(%bx) /* UNDI code size */
- pushw %es:0x28(%bx) /* UNDI data segment */
- pushw %es:0x2e(%bx) /* UNDI data size */
-
- /* Print "!PXE at <address>" */
- movw $10f, %si
- jmp check_have_stack
- .section ".prefix.data", "aw", @progbits
-10: .asciz " !PXE at "
- .previous
-
-is_valid_ppxe:
- cmpl $0x45585021, %es:(%bx)
- jne 1f
- movzbw %es:4(%bx), %cx
- cmpw $0x58, %cx
- jae is_valid_checksum
-1:
- ret
-
-is_valid_pxenv:
- cmpl $0x4e455850, %es:(%bx)
- jne 1b
- cmpw $0x2b56, %es:4(%bx)
- jne 1b
- movzbw %es:8(%bx), %cx
- cmpw $0x28, %cx
- jb 1b
-
-is_valid_checksum:
- pushw %ax
- movw %bx, %si
- xorw %ax, %ax
-2:
- es lodsb
- addb %al, %ah
- loopw 2b
- popw %ax
- ret
-
-memory_scan_ppxe:
- movw $is_valid_ppxe, %dx
- jmp memory_scan_common
-
-memory_scan_pxenv:
- movw $is_valid_pxenv, %dx
-
-memory_scan_common:
- movw %fs:(0x13), %ax
- shlw $6, %ax
- decw %ax
-1: incw %ax
- cmpw $( 0xa000 - 1 ), %ax
- ja 2f
- movw %ax, %es
- xorw %bx, %bx
- call *%dx
- jne 1b
-2: ret
-
-/*****************************************************************************
- * Sanity check: we must have an entry point
- *****************************************************************************
- */
-check_have_stack:
- /* Save common values pushed onto the stack */
- popl undi_data_segoff
- popl undi_code_segoff
- popl entry_segoff
-
- /* Print have !PXE/PXENV+ message; structure pointer in %es:%bx */
- call print_message
- call print_segoff
- movb $( ',' ), %al
- call print_character
-
- /* Check for entry point */
- movl entry_segoff, %eax
- testl %eax, %eax
- jnz 99f
- /* No entry point: print message and skip everything else */
-stack_not_found:
- movw $10f, %si
- call print_message
- jmp finished
- .section ".prefix.data", "aw", @progbits
-10: .asciz " No PXE stack found!\n"
- .previous
-99:
-
-/*****************************************************************************
- * Calculate base memory usage by UNDI
- *****************************************************************************
- */
-find_undi_basemem_usage:
- movw undi_code_segment, %ax
- movw undi_code_size, %bx
- movw undi_data_segment, %cx
- movw undi_data_size, %dx
- cmpw %ax, %cx
- ja 1f
- xchgw %ax, %cx
- xchgw %bx, %dx
-1: /* %ax:%bx now describes the lower region, %cx:%dx the higher */
- shrw $6, %ax /* Round down to nearest kB */
- movw %ax, undi_fbms_start
- addw $0x0f, %dx /* Round up to next segment */
- shrw $4, %dx
- addw %dx, %cx
- addw $((1024 / 16) - 1), %cx /* Round up to next kB */
- shrw $6, %cx
- movw %cx, undi_fbms_end
-
-/*****************************************************************************
- * Print information about detected PXE stack
- *****************************************************************************
- */
-print_structure_information:
- /* Print entry point */
- movw $10f, %si
- call print_message
- les entry_segoff, %bx
- call print_segoff
- .section ".prefix.data", "aw", @progbits
-10: .asciz " entry point at "
- .previous
- /* Print UNDI code segment */
- movw $10f, %si
- call print_message
- les undi_code_segoff, %bx
- call print_segoff
- .section ".prefix.data", "aw", @progbits
-10: .asciz "\n UNDI code segment "
- .previous
- /* Print UNDI data segment */
- movw $10f, %si
- call print_message
- les undi_data_segoff, %bx
- call print_segoff
- .section ".prefix.data", "aw", @progbits
-10: .asciz ", data segment "
- .previous
- /* Print UNDI memory usage */
- movw $10f, %si
- call print_message
- movw undi_fbms_start, %ax
- call print_word
- movb $( '-' ), %al
- call print_character
- movw undi_fbms_end, %ax
- call print_word
- movw $20f, %si
- call print_message
- .section ".prefix.data", "aw", @progbits
-10: .asciz " ("
-20: .asciz "kB)\n"
- .previous
-
-/*****************************************************************************
- * Determine physical device
- *****************************************************************************
- */
-get_physical_device:
- /* Issue PXENV_UNDI_GET_NIC_TYPE */
- movw $PXENV_UNDI_GET_NIC_TYPE, %bx
- call pxe_call
- jnc 1f
- call print_pxe_error
- jmp no_physical_device
-1: /* Determine physical device type */
- movb ( pxe_parameter_structure + 0x02 ), %al
- cmpb $2, %al
- je pci_physical_device
- jmp no_physical_device
-
-pci_physical_device:
- /* Record PCI bus:dev.fn and vendor/device IDs */
- movl ( pxe_parameter_structure + 0x03 ), %eax
- movl %eax, pci_vendor
- movw ( pxe_parameter_structure + 0x0b ), %ax
- movw %ax, pci_busdevfn
- movw $10f, %si
- call print_message
- call print_pci_busdevfn
- jmp 99f
- .section ".prefix.data", "aw", @progbits
-10: .asciz " UNDI device is PCI "
- .previous
-
-no_physical_device:
- /* No device found, or device type not understood */
- movw $10f, %si
- call print_message
- .section ".prefix.data", "aw", @progbits
-10: .asciz " Unable to determine UNDI physical device"
- .previous
-
-99:
-
-/*****************************************************************************
- * Determine interface type
- *****************************************************************************
- */
-get_iface_type:
- /* Issue PXENV_UNDI_GET_IFACE_INFO */
- movw $PXENV_UNDI_GET_IFACE_INFO, %bx
- call pxe_call
- jnc 1f
- call print_pxe_error
- jmp 99f
-1: /* Print interface type */
- movw $10f, %si
- call print_message
- leaw ( pxe_parameter_structure + 0x02 ), %si
- call print_message
- .section ".prefix.data", "aw", @progbits
-10: .asciz ", type "
- .previous
- /* Check for "Etherboot" interface type */
- cmpl $EB_MAGIC_1, ( pxe_parameter_structure + 0x02 )
- jne 99f
- cmpl $EB_MAGIC_2, ( pxe_parameter_structure + 0x06 )
- jne 99f
- movw $10f, %si
- call print_message
- .section ".prefix.data", "aw", @progbits
-10: .asciz " (workaround enabled)"
- .previous
- /* Flag Etherboot workarounds as required */
- orw $PXE_HACK_EB54, pxe_hacks
-
-99: movb $0x0a, %al
- call print_character
-
-/*****************************************************************************
- * Leave NIC in a safe state
- *****************************************************************************
- */
-#ifndef PXELOADER_KEEP_PXE
-shutdown_nic:
- /* Issue PXENV_UNDI_SHUTDOWN */
- movw $PXENV_UNDI_SHUTDOWN, %bx
- call pxe_call
- jnc 1f
- call print_pxe_error
-1:
-unload_base_code:
- /* Etherboot treats PXENV_UNLOAD_STACK as PXENV_STOP_UNDI, so
- * we must not issue this call if the underlying stack is
- * Etherboot and we were not intending to issue a PXENV_STOP_UNDI.
- */
-#ifdef PXELOADER_KEEP_UNDI
- testw $PXE_HACK_EB54, pxe_hacks
- jnz 99f
-#endif /* PXELOADER_KEEP_UNDI */
- /* Issue PXENV_UNLOAD_STACK */
- movw $PXENV_UNLOAD_STACK, %bx
- call pxe_call
- jnc 1f
- call print_pxe_error
- jmp 99f
-1: /* Free base memory used by PXE base code */
- movw undi_fbms_start, %ax
- movw %fs:(0x13), %bx
- call free_basemem
-99:
- andw $~( UNDI_FL_INITIALIZED | UNDI_FL_KEEP_ALL ), flags
-#endif /* PXELOADER_KEEP_PXE */
-
-/*****************************************************************************
- * Unload UNDI driver
- *****************************************************************************
- */
-#ifndef PXELOADER_KEEP_UNDI
-unload_undi:
- /* Issue PXENV_STOP_UNDI */
- movw $PXENV_STOP_UNDI, %bx
- call pxe_call
- jnc 1f
- call print_pxe_error
- jmp 99f
-1: /* Free base memory used by UNDI */
- movw undi_fbms_end, %ax
- movw undi_fbms_start, %bx
- call free_basemem
- /* Clear UNDI_FL_STARTED */
- andw $~UNDI_FL_STARTED, flags
-99:
-#endif /* PXELOADER_KEEP_UNDI */
-
-/*****************************************************************************
- * Print remaining free base memory
- *****************************************************************************
- */
-print_free_basemem:
- movw $10f, %si
- call print_message
- movw %fs:(0x13), %ax
- call print_word
- movw $20f, %si
- call print_message
- .section ".prefix.data", "aw", @progbits
-10: .asciz " "
-20: .asciz "kB free base memory after PXE unload\n"
- .previous
-
-/*****************************************************************************
- * Exit point
- *****************************************************************************
- */
-finished:
- jmp run_gpxe
-
-/*****************************************************************************
- * Subroutine: print segment:offset address
- *
- * Parameters:
- * %es:%bx : segment:offset address to print
- * %ds:di : output buffer (or %di=0 to print to console)
- * Returns:
- * %ds:di : next character in output buffer (if applicable)
- *****************************************************************************
- */
-print_segoff:
- /* Preserve registers */
- pushw %ax
- /* Print "<segment>:offset" */
- movw %es, %ax
- call print_hex_word
- movb $( ':' ), %al
- call print_character
- movw %bx, %ax
- call print_hex_word
- /* Restore registers and return */
- popw %ax
- ret
-
-/*****************************************************************************
- * Subroutine: print decimal word
- *
- * Parameters:
- * %ax : word to print
- * %ds:di : output buffer (or %di=0 to print to console)
- * Returns:
- * %ds:di : next character in output buffer (if applicable)
- *****************************************************************************
- */
-print_word:
- /* Preserve registers */
- pushw %ax
- pushw %bx
- pushw %cx
- pushw %dx
- /* Build up digit sequence on stack */
- movw $10, %bx
- xorw %cx, %cx
-1: xorw %dx, %dx
- divw %bx, %ax
- pushw %dx
- incw %cx
- testw %ax, %ax
- jnz 1b
- /* Print digit sequence */
-1: popw %ax
- call print_hex_nibble
- loop 1b
- /* Restore registers and return */
- popw %dx
- popw %cx
- popw %bx
- popw %ax
- ret
-
-/*****************************************************************************
- * Subroutine: zero 1kB block of base memory
- *
- * Parameters:
- * %bx : block to zero (in kB)
- * Returns:
- * Nothing
- *****************************************************************************
- */
-zero_kb:
- /* Preserve registers */
- pushw %ax
- pushw %cx
- pushw %di
- pushw %es
- /* Zero block */
- movw %bx, %ax
- shlw $6, %ax
- movw %ax, %es
- movw $0x400, %cx
- xorw %di, %di
- xorw %ax, %ax
- rep stosb
- /* Restore registers and return */
- popw %es
- popw %di
- popw %cx
- popw %ax
- ret
-
-/*****************************************************************************
- * Subroutine: free and zero base memory
- *
- * Parameters:
- * %ax : Desired new free base memory counter (in kB)
- * %bx : Expected current free base memory counter (in kB)
- * %fs : BIOS data segment (0x40)
- * Returns:
- * None
- *
- * The base memory from %bx kB to %ax kB is unconditionally zeroed.
- * It will be freed if and only if the expected current free base
- * memory counter (%bx) matches the actual current free base memory
- * counter in 0x40:0x13; if this does not match then the memory will
- * be leaked.
- *****************************************************************************
- */
-free_basemem:
- /* Zero base memory */
- pushw %bx
-1: cmpw %bx, %ax
- je 2f
- call zero_kb
- incw %bx
- jmp 1b
-2: popw %bx
- /* Free base memory */
- cmpw %fs:(0x13), %bx /* Update FBMS only if "old" value */
- jne 1f /* is correct */
-1: movw %ax, %fs:(0x13)
- ret
-
-/*****************************************************************************
- * Subroutine: make a PXE API call. Works with either !PXE or PXENV+ API.
- *
- * Parameters:
- * %bx : PXE API call number
- * %ds:pxe_parameter_structure : Parameters for PXE API call
- * Returns:
- * %ax : PXE status code (not exit code)
- * CF set if %ax is non-zero
- *****************************************************************************
- */
-pxe_call:
- /* Preserve registers */
- pushw %di
- pushw %es
- /* Set up registers for PXENV+ API. %bx already set up */
- pushw %ds
- popw %es
- movw $pxe_parameter_structure, %di
- /* Set up stack for !PXE API */
- pushw %es
- pushw %di
- pushw %bx
- /* Make the API call */
- lcall *entry_segoff
- /* Reset the stack */
- addw $6, %sp
- movw pxe_parameter_structure, %ax
- clc
- testw %ax, %ax
- jz 1f
- stc
-1: /* Clear direction flag, for the sake of sanity */
- cld
- /* Restore registers and return */
- popw %es
- popw %di
- ret
-
-/*****************************************************************************
- * Subroutine: print PXE API call error message
- *
- * Parameters:
- * %ax : PXE status code
- * %bx : PXE API call number
- * Returns:
- * Nothing
- *****************************************************************************
- */
-print_pxe_error:
- pushw %si
- movw $10f, %si
- call print_message
- xchgw %ax, %bx
- call print_hex_word
- movw $20f, %si
- call print_message
- xchgw %ax, %bx
- call print_hex_word
- movw $30f, %si
- call print_message
- popw %si
- ret
- .section ".prefix.data", "aw", @progbits
-10: .asciz " UNDI API call "
-20: .asciz " failed: status code "
-30: .asciz "\n"
- .previous
-
-/*****************************************************************************
- * PXE data structures
- *****************************************************************************
- */
- .section ".prefix.data"
-
-pxe_esp: .long 0
-pxe_ss: .word 0
-
-pxe_parameter_structure: .fill 64
-
-undi_code_segoff:
-undi_code_size: .word 0
-undi_code_segment: .word 0
-
-undi_data_segoff:
-undi_data_size: .word 0
-undi_data_segment: .word 0
-
-pxe_hacks: .word 0
-
-/* The following fields are part of a struct undi_device */
-
-undi_device:
-
-pxenv_segoff:
-pxenv_offset: .word 0
-pxenv_segment: .word 0
-
-ppxe_segoff:
-ppxe_offset: .word 0
-ppxe_segment: .word 0
-
-entry_segoff:
-entry_offset: .word 0
-entry_segment: .word 0
-
-undi_fbms_start: .word 0
-undi_fbms_end: .word 0
-
-pci_busdevfn: .word UNDI_NO_PCI_BUSDEVFN
-isapnp_csn: .word UNDI_NO_ISAPNP_CSN
-isapnp_read_port: .word UNDI_NO_ISAPNP_READ_PORT
-
-pci_vendor: .word 0
-pci_device: .word 0
-flags:
- .word ( UNDI_FL_INITIALIZED | UNDI_FL_STARTED | UNDI_FL_KEEP_ALL )
-
- .equ undi_device_size, ( . - undi_device )
-
-/*****************************************************************************
- * Run gPXE main code
- *****************************************************************************
- */
- .section ".prefix"
-run_gpxe:
- /* Install gPXE */
- call install
-
- /* Set up real-mode stack */
- movw %bx, %ss
- movw $_estack16, %sp
-
-#ifdef PXELOADER_KEEP_UNDI
- /* Copy our undi_device structure to the preloaded_undi variable */
- movw %bx, %es
- movw $preloaded_undi, %di
- movw $undi_device, %si
- movw $undi_device_size, %cx
- rep movsb
-#endif
-
- /* Retrieve PXE %ss:esp */
- movw pxe_ss, %di
- movl pxe_esp, %ebp
-
- /* Jump to .text16 segment with %ds pointing to .data16 */
- movw %bx, %ds
- pushw %ax
- pushw $1f
- lret
- .section ".text16", "ax", @progbits
-1:
- /* Update the exit hook */
- movw %cs,pxe_exit_hook+2
- push %ax
- mov $2f,%ax
- mov %ax,pxe_exit_hook
- pop %ax
-
- /* Run main program */
- pushl $main
- pushw %cs
- call prot_call
- popl %ecx /* discard */
-
- /* Uninstall gPXE */
- call uninstall
-
- /* Restore PXE stack */
- movw %di, %ss
- movl %ebp, %esp
-
- /* Jump to hook if applicable */
- ljmpw *pxe_exit_hook
-
-2: /* Check PXE stack magic */
- popl %eax
- cmpl $STACK_MAGIC, %eax
- jne 1f
-
- /* PXE stack OK: return to caller */
- popw %ds
- popw %es
- popw %fs
- popw %gs
- popal
- popfl
- xorw %ax, %ax /* Return success */
- lret
-
-1: /* PXE stack corrupt or removed: use INT 18 */
- int $0x18
- .previous
diff --git a/gpxe/src/arch/i386/prefix/romprefix.S b/gpxe/src/arch/i386/prefix/romprefix.S
deleted file mode 100644
index 02e54976..00000000
--- a/gpxe/src/arch/i386/prefix/romprefix.S
+++ /dev/null
@@ -1,1079 +0,0 @@
-/* At entry, the processor is in 16 bit real mode and the code is being
- * executed from an address it was not linked to. Code must be pic and
- * 32 bit sensitive until things are fixed up.
- *
- * Also be very careful as the stack is at the rear end of the interrupt
- * table so using a noticeable amount of stack space is a no-no.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER )
-
-#include <config/general.h>
-
-#define PNP_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) )
-#define PMM_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'M' << 16 ) + ( 'M' << 24 ) )
-#define PCI_SIGNATURE ( 'P' + ( 'C' << 8 ) + ( 'I' << 16 ) + ( ' ' << 24 ) )
-#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
-#define PNP_GET_BBS_VERSION 0x60
-#define PMM_ALLOCATE 0x0000
-#define PMM_DEALLOCATE 0x0002
-
-/* ROM banner timeout. Based on the configurable BANNER_TIMEOUT in
- * config.h, but converted to a number of (18Hz) timer ticks, and
- * doubled to allow for BIOSes that switch video modes immediately
- * beforehand, so rendering the message almost invisible to the user.
- */
-#define ROM_BANNER_TIMEOUT ( 2 * ( 18 * BANNER_TIMEOUT ) / 10 )
-
-/* We can load a ROM in two ways: have the BIOS load all of it (.rom prefix)
- * or have the BIOS load a stub that loads the rest using PCI (.xrom prefix).
- * The latter is not as widely supported, but allows the use of large ROMs
- * on some systems with crowded option ROM space.
- */
-
-#ifdef LOAD_ROM_FROM_PCI
-#define ROM_SIZE_VALUE _prefix_filesz_sect /* Amount to load in BIOS */
-#else
-#define ROM_SIZE_VALUE 0 /* Load amount (before compr. fixup) */
-#endif
-
-
- .text
- .code16
- .arch i386
- .section ".prefix", "ax", @progbits
-
- .org 0x00
-romheader:
- .word 0xAA55 /* BIOS extension signature */
-romheader_size: .byte ROM_SIZE_VALUE /* Size in 512-byte blocks */
- jmp init /* Initialisation vector */
-checksum:
- .byte 0, 0
-real_size:
- .word 0
- .org 0x16
- .word undiheader
- .org 0x18
- .word pciheader
- .org 0x1a
- .word pnpheader
- .size romheader, . - romheader
-
- .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
-#ifndef LOAD_ROM_FROM_PCI
- .ascii "ADDB"
- .long romheader_size
- .long 512
- .long 0
-#endif
- .ascii "ADDB"
- .long real_size
- .long 512
- .long 0
- .previous
-
-pciheader:
- .ascii "PCIR" /* Signature */
- .word pci_vendor_id /* Vendor identification */
- .word pci_device_id /* Device identification */
- .word 0x0000 /* Device list pointer */
- .word pciheader_len /* PCI data structure length */
- .byte 0x03 /* PCI data structure revision */
- .byte 0x02, 0x00, 0x00 /* Class code */
-pciheader_image_length:
- .word ROM_SIZE_VALUE /* Image length */
- .word 0x0001 /* Revision level */
- .byte 0x00 /* Code type */
- .byte 0x80 /* Last image indicator */
-pciheader_runtime_length:
- .word ROM_SIZE_VALUE /* Maximum run-time image length */
- .word 0x0000 /* Configuration utility code header */
- .word 0x0000 /* DMTF CLP entry point */
- .equ pciheader_len, . - pciheader
- .size pciheader, . - pciheader
-
-#ifndef LOAD_ROM_FROM_PCI
- .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
- .ascii "ADDW"
- .long pciheader_image_length
- .long 512
- .long 0
- .ascii "ADDW"
- .long pciheader_runtime_length
- .long 512
- .long 0
- .previous
-#endif
-
-pnpheader:
- .ascii "$PnP" /* Signature */
- .byte 0x01 /* Structure revision */
- .byte ( pnpheader_len / 16 ) /* Length (in 16 byte increments) */
- .word 0x0000 /* Offset of next header */
- .byte 0x00 /* Reserved */
- .byte 0x00 /* Checksum */
- .long 0x00000000 /* Device identifier */
- .word mfgstr /* Manufacturer string */
- .word prodstr /* Product name */
- .byte 0x02 /* Device base type code */
- .byte 0x00 /* Device sub-type code */
- .byte 0x00 /* Device interface type code */
- .byte 0xf4 /* Device indicator */
- .word 0x0000 /* Boot connection vector */
- .word 0x0000 /* Disconnect vector */
- .word bev_entry /* Boot execution vector */
- .word 0x0000 /* Reserved */
- .word 0x0000 /* Static resource information vector*/
- .equ pnpheader_len, . - pnpheader
- .size pnpheader, . - pnpheader
-
-/* Manufacturer string */
-mfgstr:
- .asciz "http://etherboot.org"
- .size mfgstr, . - mfgstr
-
-/* Product string
- *
- * Defaults to PRODUCT_SHORT_NAME. If the ROM image is writable at
- * initialisation time, it will be filled in to include the PCI
- * bus:dev.fn number of the card as well.
- */
-prodstr:
- .ascii PRODUCT_SHORT_NAME
-prodstr_separator:
- .byte 0
- .ascii "(PCI "
-prodstr_pci_id:
- .asciz "xx:xx.x)" /* Filled in by init code */
- .size prodstr, . - prodstr
-
- .globl undiheader
- .weak undiloader
-undiheader:
- .ascii "UNDI" /* Signature */
- .byte undiheader_len /* Length of structure */
- .byte 0 /* Checksum */
- .byte 0 /* Structure revision */
- .byte 0,1,2 /* PXE version: 2.1.0 */
- .word undiloader /* Offset to loader routine */
- .word _data16_memsz /* Stack segment size */
- .word _data16_memsz /* Data segment size */
- .word _text16_memsz /* Code segment size */
- .ascii "PCIR" /* Bus type */
- .equ undiheader_len, . - undiheader
- .size undiheader, . - undiheader
-
-/* Initialisation (called once during POST)
- *
- * Determine whether or not this is a PnP system via a signature
- * check. If it is PnP, return to the PnP BIOS indicating that we are
- * a boot-capable device; the BIOS will call our boot execution vector
- * if it wants to boot us. If it is not PnP, hook INT 19.
- */
-init:
- /* Preserve registers, clear direction flag, set %ds=%cs */
- pushaw
- pushw %ds
- pushw %es
- pushw %fs
- pushw %gs
- cld
- pushw %cs
- popw %ds
-
- /* Shuffle some registers around. We need %di available for
- * the print_xxx functions, and in a register that's
- * addressable from %es, so shuffle as follows:
- *
- * %di (pointer to PnP structure) => %bx
- * %bx (runtime segment address, for PCI 3.0) => %gs
- */
- movw %bx, %gs
- movw %di, %bx
-
- /* Print message as early as possible */
- movw $init_message, %si
- xorw %di, %di
- call print_message
- call print_pci_busdevfn
-
-#ifdef LOAD_ROM_FROM_PCI
- /* Save PCI bus:dev.fn for later use */
- movw %ax, pci_busdevfn
-#endif
-
- /* Fill in product name string, if possible */
- movw $prodstr_pci_id, %di
- call print_pci_busdevfn
- movb $( ' ' ), prodstr_separator
-
- /* Print segment address */
- movb $( ' ' ), %al
- xorw %di, %di
- call print_character
- movw %cs, %ax
- call print_hex_word
-
- /* Check for PCI BIOS version */
- pushl %ebx
- pushl %edx
- pushl %edi
- stc
- movw $0xb101, %ax
- int $0x1a
- jc no_pci3
- cmpl $PCI_SIGNATURE, %edx
- jne no_pci3
- testb %ah, %ah
- jnz no_pci3
-#ifdef LOAD_ROM_FROM_PCI
- incb pcibios_present
-#endif
- movw $init_message_pci, %si
- xorw %di, %di
- call print_message
- movb %bh, %al
- call print_hex_nibble
- movb $( '.' ), %al
- call print_character
- movb %bl, %al
- call print_hex_byte
- cmpb $3, %bh
- jb no_pci3
- /* PCI >=3.0: leave %gs as-is if sane */
- movw %gs, %ax
- cmpw $0xa000, %ax /* Insane if %gs < 0xa000 */
- jb pci3_insane
- movw %cs, %bx /* Sane if %cs == %gs */
- cmpw %bx, %ax
- je 1f
- movzbw romheader_size, %cx /* Sane if %cs+len <= %gs */
- shlw $5, %cx
- addw %cx, %bx
- cmpw %bx, %ax
- jae 1f
- movw %cs, %bx /* Sane if %gs+len <= %cs */
- addw %cx, %ax
- cmpw %bx, %ax
- jbe 1f
-pci3_insane: /* PCI 3.0 with insane %gs value: print error and ignore %gs */
- movb $( '!' ), %al
- call print_character
- movw %gs, %ax
- call print_hex_word
-no_pci3:
- /* PCI <3.0: set %gs (runtime segment) = %cs (init-time segment) */
- pushw %cs
- popw %gs
-1: popl %edi
- popl %edx
- popl %ebx
-
- /* Check for PnP BIOS. Although %es:di should point to the
- * PnP BIOS signature on entry, some BIOSes fail to do this.
- */
- movw $( 0xf000 - 1 ), %bx
-pnp_scan:
- incw %bx
- jz no_pnp
- movw %bx, %es
- cmpl $PNP_SIGNATURE, %es:0
- jne pnp_scan
- xorw %dx, %dx
- xorw %si, %si
- movzbw %es:5, %cx
-1: es lodsb
- addb %al, %dl
- loop 1b
- jnz pnp_scan
- /* Is PnP: print PnP message */
- movw $init_message_pnp, %si
- xorw %di, %di
- call print_message
- /* Check for BBS */
- pushw %es:0x1b /* Real-mode data segment */
- pushw %ds /* &(bbs_version) */
- pushw $bbs_version
- pushw $PNP_GET_BBS_VERSION
- lcall *%es:0xd
- addw $8, %sp
- testw %ax, %ax
- je got_bbs
-no_pnp: /* Not PnP-compliant - therefore cannot be BBS-compliant */
-no_bbs: /* Not BBS-compliant - must hook INT 19 */
- movw $init_message_int19, %si
- xorw %di, %di
- call print_message
- xorw %ax, %ax
- movw %ax, %es
- pushl %es:( 0x19 * 4 )
- popl orig_int19
- pushw %gs /* %gs contains runtime %cs */
- pushw $int19_entry
- popl %es:( 0x19 * 4 )
- jmp bbs_done
-got_bbs: /* BBS compliant - no need to hook INT 19 */
- movw $init_message_bbs, %si
- xorw %di, %di
- call print_message
-bbs_done:
-
- /* Check for PMM */
- movw $( 0xe000 - 1 ), %bx
-pmm_scan:
- incw %bx
- jz no_pmm
- movw %bx, %es
- cmpl $PMM_SIGNATURE, %es:0
- jne pmm_scan
- xorw %dx, %dx
- xorw %si, %si
- movzbw %es:5, %cx
-1: es lodsb
- addb %al, %dl
- loop 1b
- jnz pmm_scan
- /* PMM found: print PMM message */
- movw $init_message_pmm, %si
- xorw %di, %di
- call print_message
- /* We have PMM and so a 1kB stack: preserve upper register halves */
- pushal
- /* Calculate required allocation size in %esi */
- movzwl real_size, %eax
- shll $9, %eax
- addl $_textdata_memsz, %eax
- orw $0xffff, %ax /* Ensure allocation size is at least 64kB */
- bsrl %eax, %ecx
- subw $15, %cx /* Round up and convert to 64kB count */
- movw $1, %si
- shlw %cl, %si
-pmm_loop:
- /* Try to allocate block via PMM */
- pushw $0x0006 /* Aligned, extended memory */
- pushl $0xffffffff /* No handle */
- movzwl %si, %eax
- shll $12, %eax
- pushl %eax /* Allocation size in paragraphs */
- pushw $PMM_ALLOCATE
- lcall *%es:7
- addw $12, %sp
- /* Abort if allocation fails */
- testw %dx, %dx /* %ax==0 even on success, since align>=64kB */
- jz pmm_fail
- /* If block has A20==1, free block and try again with twice
- * the allocation size (and hence alignment).
- */
- testw $0x0010, %dx
- jz got_pmm
- pushw %dx
- pushw $0
- pushw $PMM_DEALLOCATE
- lcall *%es:7
- addw $6, %sp
- addw %si, %si
- jmp pmm_loop
-got_pmm: /* PMM allocation succeeded */
- movw %dx, ( image_source + 2 )
- movw %dx, %ax
- xorw %di, %di
- call print_hex_word
- movb $( '@' ), %al
- call print_character
- movw %si, %ax
- call print_hex_byte
-pmm_copy:
- /* Copy ROM to PMM block */
- xorw %ax, %ax
- movw %ax, %es
- movl image_source, %edi
- xorl %esi, %esi
- movzbl romheader_size, %ecx
- shll $9, %ecx
- addr32 rep movsb /* PMM presence implies flat real mode */
- movl %edi, decompress_to
- /* Shrink ROM */
- movb $_prefix_memsz_sect, romheader_size
-#if defined(SHRINK_WITHOUT_PMM) || defined(LOAD_ROM_FROM_PCI)
- jmp pmm_done
-pmm_fail:
- /* Print marker and copy ourselves to high memory */
- movl $HIGHMEM_LOADPOINT, image_source
- xorw %di, %di
- movb $( '!' ), %al
- call print_character
- jmp pmm_copy
-pmm_done:
-#else
-pmm_fail:
-#endif
- /* Restore upper register halves */
- popal
-#if defined(LOAD_ROM_FROM_PCI)
- call load_from_pci
- jc load_err
- jmp load_ok
-no_pmm:
- /* Cannot continue without PMM - print error message */
- xorw %di, %di
- movw $init_message_no_pmm, %si
- call print_message
-load_err:
- /* Wait for five seconds to let user see message */
- movw $90, %cx
-1: call wait_for_tick
- loop 1b
- /* Mark environment as invalid and return */
- movl $0, decompress_to
- jmp out
-
-load_ok:
-#else
-no_pmm:
-#endif
- /* Update checksum */
- xorw %bx, %bx
- xorw %si, %si
- movzbw romheader_size, %cx
- shlw $9, %cx
-1: lodsb
- addb %al, %bl
- loop 1b
- subb %bl, checksum
-
- /* Copy self to option ROM space. Required for PCI3.0, which
- * loads us to a temporary location in low memory. Will be a
- * no-op for lower PCI versions.
- */
- movb $( ' ' ), %al
- xorw %di, %di
- call print_character
- movw %gs, %ax
- call print_hex_word
- movzbw romheader_size, %cx
- shlw $9, %cx
- movw %ax, %es
- xorw %si, %si
- xorw %di, %di
- cs rep movsb
-
- /* Prompt for POST-time shell */
- movw $init_message_prompt, %si
- xorw %di, %di
- call print_message
- movw $prodstr, %si
- call print_message
- movw $init_message_dots, %si
- call print_message
- /* Wait for Ctrl-B */
- movw $0xff02, %bx
- call wait_for_key
- /* Clear prompt */
- pushf
- xorw %di, %di
- call print_kill_line
- movw $init_message_done, %si
- call print_message
- popf
- jnz out
- /* Ctrl-B was pressed: invoke gPXE. The keypress will be
- * picked up by the initial shell prompt, and we will drop
- * into a shell.
- */
- pushw %cs
- call exec
-out:
- /* Restore registers */
- popw %gs
- popw %fs
- popw %es
- popw %ds
- popaw
-
- /* Indicate boot capability to PnP BIOS, if present */
- movw $0x20, %ax
- lret
- .size init, . - init
-
-/*
- * Note to hardware vendors:
- *
- * If you wish to brand this boot ROM, please do so by defining the
- * strings PRODUCT_NAME and PRODUCT_SHORT_NAME in config/general.h.
- *
- * While nothing in the GPL prevents you from removing all references
- * to gPXE or http://etherboot.org, we prefer you not to do so.
- *
- * If you have an OEM-mandated branding requirement that cannot be
- * satisfied simply by defining PRODUCT_NAME and PRODUCT_SHORT_NAME,
- * please contact us.
- *
- * [ Including an ASCII NUL in PRODUCT_NAME is considered to be
- * bypassing the spirit of this request! ]
- */
-init_message:
- .ascii "\n"
- .ascii PRODUCT_NAME
- .ascii "\n"
- .asciz "gPXE (http://etherboot.org) - "
- .size init_message, . - init_message
-init_message_pci:
- .asciz " PCI"
- .size init_message_pci, . - init_message_pci
-init_message_pnp:
- .asciz " PnP"
- .size init_message_pnp, . - init_message_pnp
-init_message_bbs:
- .asciz " BBS"
- .size init_message_bbs, . - init_message_bbs
-init_message_pmm:
- .asciz " PMM"
- .size init_message_pmm, . - init_message_pmm
-#ifdef LOAD_ROM_FROM_PCI
-init_message_no_pmm:
- .asciz "\nPMM required but not present!\n"
- .size init_message_no_pmm, . - init_message_no_pmm
-#endif
-init_message_int19:
- .asciz " INT19"
- .size init_message_int19, . - init_message_int19
-init_message_prompt:
- .asciz "\nPress Ctrl-B to configure "
- .size init_message_prompt, . - init_message_prompt
-init_message_dots:
- .asciz "..."
- .size init_message_dots, . - init_message_dots
-init_message_done:
- .asciz "\n\n"
- .size init_message_done, . - init_message_done
-
-/* ROM image location
- *
- * May be either within option ROM space, or within PMM-allocated block.
- */
- .globl image_source
-image_source:
- .long 0
- .size image_source, . - image_source
-
-/* Temporary decompression area
- *
- * May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block.
- * If a PCI ROM load fails, this will be set to zero.
- */
- .globl decompress_to
-decompress_to:
- .long HIGHMEM_LOADPOINT
- .size decompress_to, . - decompress_to
-
-#ifdef LOAD_ROM_FROM_PCI
-
-/* Set if the PCI BIOS is present, even <3.0 */
-pcibios_present:
- .byte 0
- .byte 0 /* for alignment */
- .size pcibios_present, . - pcibios_present
-
-/* PCI bus:device.function word
- *
- * Filled in by init in the .xrom case, so the remainder of the ROM
- * can be located.
- */
-pci_busdevfn:
- .word 0
- .size pci_busdevfn, . - pci_busdevfn
-
-#endif
-
-/* BBS version
- *
- * Filled in by BBS BIOS. We ignore the value.
- */
-bbs_version:
- .word 0
- .size bbs_version, . - bbs_version
-
-/* Boot Execution Vector entry point
- *
- * Called by the PnP BIOS when it wants to boot us.
- */
-bev_entry:
- pushw %cs
- call exec
- lret
- .size bev_entry, . - bev_entry
-
-
-#ifdef LOAD_ROM_FROM_PCI
-
-#define PCI_ROM_ADDRESS 0x30 /* Bits 31:11 address, 10:1 reserved */
-#define PCI_ROM_ADDRESS_ENABLE 0x00000001
-#define PCI_ROM_ADDRESS_MASK 0xfffff800
-
-#define PCIBIOS_READ_WORD 0xb109
-#define PCIBIOS_READ_DWORD 0xb10a
-#define PCIBIOS_WRITE_WORD 0xb10c
-#define PCIBIOS_WRITE_DWORD 0xb10d
-
-/* Determine size of PCI BAR
- *
- * %bx : PCI bus:dev.fn to probe
- * %di : Address of BAR to find size of
- * %edx : Mask of address bits within BAR
- *
- * %ecx : Size for a memory resource,
- * 1 for an I/O resource (bit 0 set).
- * CF : Set on error or nonexistent device (all-ones read)
- *
- * All other registers saved.
- */
-pci_bar_size:
- /* Save registers */
- pushw %ax
- pushl %esi
- pushl %edx
-
- /* Read current BAR value */
- movw $PCIBIOS_READ_DWORD, %ax
- int $0x1a
-
- /* Check for device existence and save it */
- testb $1, %cl /* I/O bit? */
- jz 1f
- andl $1, %ecx /* If so, exit with %ecx = 1 */
- jmp 99f
-1: notl %ecx
- testl %ecx, %ecx /* Set ZF iff %ecx was all-ones */
- notl %ecx
- jnz 1f
- stc /* All ones - exit with CF set */
- jmp 99f
-1: movl %ecx, %esi /* Save in %esi */
-
- /* Write all ones to BAR */
- movl %edx, %ecx
- movw $PCIBIOS_WRITE_DWORD, %ax
- int $0x1a
-
- /* Read back BAR */
- movw $PCIBIOS_READ_DWORD, %ax
- int $0x1a
-
- /* Find decode size from least set bit in mask BAR */
- bsfl %ecx, %ecx /* Find least set bit, log2(decode size) */
- jz 1f /* Mask BAR should not be zero */
- xorl %edx, %edx
- incl %edx
- shll %cl, %edx /* %edx = decode size */
- jmp 2f
-1: xorl %edx, %edx /* Return zero size for mask BAR zero */
-
- /* Restore old BAR value */
-2: movl %esi, %ecx
- movw $PCIBIOS_WRITE_DWORD, %ax
- int $0x1a
-
- movl %edx, %ecx /* Return size in %ecx */
-
- /* Restore registers and return */
-99: popl %edx
- popl %esi
- popw %ax
- ret
-
- .size pci_bar_size, . - pci_bar_size
-
-/* PCI ROM loader
- *
- * Called from init in the .xrom case to load the non-prefix code
- * using the PCI ROM BAR.
- *
- * Returns with carry flag set on error. All registers saved.
- */
-load_from_pci:
- /*
- * Use PCI BIOS access to config space. The calls take
- *
- * %ah : 0xb1 %al : function
- * %bx : bus/dev/fn
- * %di : config space address
- * %ecx : value to write (for writes)
- *
- * %ecx : value read (for reads)
- * %ah : return code
- * CF : error indication
- *
- * All registers not used for return are preserved.
- */
-
- /* Save registers and set up %es for big real mode */
- pushal
- pushw %es
- xorw %ax, %ax
- movw %ax, %es
-
- /* Check PCI BIOS presence */
- cmpb $0, pcibios_present
- jz err_pcibios
-
- /* Load existing PCI ROM BAR */
- movw $PCIBIOS_READ_DWORD, %ax
- movw pci_busdevfn, %bx
- movw $PCI_ROM_ADDRESS, %di
- int $0x1a
-
- /* Maybe it's already enabled? */
- testb $PCI_ROM_ADDRESS_ENABLE, %cl
- jz 1f
- movb $1, %dl /* Flag indicating no deinit required */
- movl %ecx, %ebp
- jmp check_rom
-
- /* Determine PCI BAR decode size */
-1: movl $PCI_ROM_ADDRESS_MASK, %edx
- call pci_bar_size /* Returns decode size in %ecx */
- jc err_size_insane /* CF => no ROM BAR, %ecx == ffffffff */
-
- /* Check sanity of decode size */
- xorl %eax, %eax
- movw real_size, %ax
- shll $9, %eax /* %eax = ROM size */
- cmpl %ecx, %eax
- ja err_size_insane /* Insane if decode size < ROM size */
- cmpl $0x100000, %ecx
- jae err_size_insane /* Insane if decode size >= 1MB */
-
- /* Find a place to map the BAR
- * In theory we should examine e820 and all PCI BARs to find a
- * free region. However, we run at POST when e820 may not be
- * available, and memory reads of an unmapped location are
- * de facto standardized to return all-ones. Thus, we can get
- * away with searching high memory (0xf0000000 and up) on
- * multiples of the ROM BAR decode size for a sufficiently
- * large all-ones region.
- */
- movl %ecx, %edx /* Save ROM BAR size in %edx */
- movl $0xf0000000, %ebp
- xorl %eax, %eax
- notl %eax /* %eax = all ones */
-bar_search:
- movl %ebp, %edi
- movl %edx, %ecx
- shrl $2, %ecx
- addr32 repe scasl /* Scan %es:edi for anything not all-ones */
- jz bar_found
- addl %edx, %ebp
- testl $0x80000000, %ebp
- jz err_no_bar
- jmp bar_search
-
-bar_found:
- movl %edi, %ebp
- /* Save current BAR value on stack to restore later */
- movw $PCIBIOS_READ_DWORD, %ax
- movw $PCI_ROM_ADDRESS, %di
- int $0x1a
- pushl %ecx
-
- /* Map the ROM */
- movw $PCIBIOS_WRITE_DWORD, %ax
- movl %ebp, %ecx
- orb $PCI_ROM_ADDRESS_ENABLE, %cl
- int $0x1a
-
- xorb %dl, %dl /* %dl = 0 : ROM was not already mapped */
-check_rom:
- /* Check and copy ROM - enter with %dl set to skip unmapping,
- * %ebp set to mapped ROM BAR address.
- * We check up to prodstr_separator for equality, since anything past
- * that may have been modified. Since our check includes the checksum
- * byte over the whole ROM stub, that should be sufficient.
- */
- xorb %dh, %dh /* %dh = 0 : ROM did not fail integrity check */
-
- /* Verify ROM integrity */
- xorl %esi, %esi
- movl %ebp, %edi
- movl $prodstr_separator, %ecx
- addr32 repe cmpsb
- jz copy_rom
- incb %dh /* ROM failed integrity check */
- movl %ecx, %ebp /* Save number of bytes left */
- jmp skip_load
-
-copy_rom:
- /* Print BAR address and indicate whether we mapped it ourselves */
- movb $( ' ' ), %al
- xorw %di, %di
- call print_character
- movl %ebp, %eax
- call print_hex_dword
- movb $( '-' ), %al /* '-' for self-mapped */
- subb %dl, %al
- subb %dl, %al /* '+' = '-' - 2 for BIOS-mapped */
- call print_character
-
- /* Copy ROM at %ebp to PMM or highmem block */
- movl %ebp, %esi
- movl image_source, %edi
- movzwl real_size, %ecx
- shll $9, %ecx
- addr32 es rep movsb
- movl %edi, decompress_to
-skip_load:
- testb %dl, %dl /* Was ROM already mapped? */
- jnz skip_unmap
-
- /* Unmap the ROM by restoring old ROM BAR */
- movw $PCIBIOS_WRITE_DWORD, %ax
- movw $PCI_ROM_ADDRESS, %di
- popl %ecx
- int $0x1a
-
-skip_unmap:
- /* Error handling */
- testb %dh, %dh
- jnz err_rom_invalid
- clc
- jmp 99f
-
-err_pcibios: /* No PCI BIOS available */
- movw $load_message_no_pcibios, %si
- xorl %eax, %eax /* "error code" is zero */
- jmp 1f
-err_size_insane: /* BAR has size (%ecx) that is insane */
- movw $load_message_size_insane, %si
- movl %ecx, %eax
- jmp 1f
-err_no_bar: /* No space of sufficient size (%edx) found */
- movw $load_message_no_bar, %si
- movl %edx, %eax
- jmp 1f
-err_rom_invalid: /* Loaded ROM does not match (%ebp bytes left) */
- movw $load_message_rom_invalid, %si
- movzbl romheader_size, %eax
- shll $9, %eax
- subl %ebp, %eax
- decl %eax /* %eax is now byte index of failure */
-
-1: /* Error handler - print message at %si and dword in %eax */
- xorw %di, %di
- call print_message
- call print_hex_dword
- stc
-99: popw %es
- popal
- ret
-
- .size load_from_pci, . - load_from_pci
-
-load_message_no_pcibios:
- .asciz "\nNo PCI BIOS found! "
- .size load_message_no_pcibios, . - load_message_no_pcibios
-
-load_message_size_insane:
- .asciz "\nROM resource has invalid size "
- .size load_message_size_insane, . - load_message_size_insane
-
-load_message_no_bar:
- .asciz "\nNo memory hole of sufficient size "
- .size load_message_no_bar, . - load_message_no_bar
-
-load_message_rom_invalid:
- .asciz "\nLoaded ROM is invalid at "
- .size load_message_rom_invalid, . - load_message_rom_invalid
-
-#endif /* LOAD_ROM_FROM_PCI */
-
-
-/* INT19 entry point
- *
- * Called via the hooked INT 19 if we detected a non-PnP BIOS. We
- * attempt to return via the original INT 19 vector (if we were able
- * to store it).
- */
-int19_entry:
- pushw %cs
- popw %ds
- /* Prompt user to press B to boot */
- movw $int19_message_prompt, %si
- xorw %di, %di
- call print_message
- movw $prodstr, %si
- call print_message
- movw $int19_message_dots, %si
- call print_message
- movw $0xdf4e, %bx
- call wait_for_key
- pushf
- xorw %di, %di
- call print_kill_line
- movw $int19_message_done, %si
- call print_message
- popf
- jz 1f
- /* Leave keypress in buffer and start gPXE. The keypress will
- * cause the usual initial Ctrl-B prompt to be skipped.
- */
- pushw %cs
- call exec
-1: /* Try to call original INT 19 vector */
- movl %cs:orig_int19, %eax
- testl %eax, %eax
- je 2f
- ljmp *%cs:orig_int19
-2: /* No chained vector: issue INT 18 as a last resort */
- int $0x18
- .size int19_entry, . - int19_entry
-orig_int19:
- .long 0
- .size orig_int19, . - orig_int19
-
-int19_message_prompt:
- .asciz "Press N to skip booting from "
- .size int19_message_prompt, . - int19_message_prompt
-int19_message_dots:
- .asciz "..."
- .size int19_message_dots, . - int19_message_dots
-int19_message_done:
- .asciz "\n\n"
- .size int19_message_done, . - int19_message_done
-
-/* Execute as a boot device
- *
- */
-exec: /* Set %ds = %cs */
- pushw %cs
- popw %ds
-
-#ifdef LOAD_ROM_FROM_PCI
- /* Don't execute if load was invalid */
- cmpl $0, decompress_to
- jne 1f
- lret
-1:
-#endif
-
- /* Print message as soon as possible */
- movw $prodstr, %si
- xorw %di, %di
- call print_message
- movw $exec_message, %si
- call print_message
-
- /* Store magic word on BIOS stack and remember BIOS %ss:sp */
- pushl $STACK_MAGIC
- movw %ss, %dx
- movw %sp, %bp
-
- /* Obtain a reasonably-sized temporary stack */
- xorw %ax, %ax
- movw %ax, %ss
- movw $0x7c00, %sp
-
- /* Install gPXE */
- movl image_source, %esi
- movl decompress_to, %edi
- call alloc_basemem
- call install_prealloc
-
- /* Set up real-mode stack */
- movw %bx, %ss
- movw $_estack16, %sp
-
- /* Jump to .text16 segment */
- pushw %ax
- pushw $1f
- lret
- .section ".text16", "awx", @progbits
-1: /* Call main() */
- pushl $main
- pushw %cs
- call prot_call
- popl %ecx /* discard */
-
- /* Uninstall gPXE */
- call uninstall
-
- /* Restore BIOS stack */
- movw %dx, %ss
- movw %bp, %sp
-
- /* Check magic word on BIOS stack */
- popl %eax
- cmpl $STACK_MAGIC, %eax
- jne 1f
- /* BIOS stack OK: return to caller */
- lret
-1: /* BIOS stack corrupt: use INT 18 */
- int $0x18
- .previous
-
-exec_message:
- .asciz " starting execution\n"
- .size exec_message, . - exec_message
-
-/* Wait for key press specified by %bl (masked by %bh)
- *
- * Used by init and INT19 code when prompting user. If the specified
- * key is pressed, it is left in the keyboard buffer.
- *
- * Returns with ZF set iff specified key is pressed.
- */
-wait_for_key:
- /* Preserve registers */
- pushw %cx
- pushw %ax
-1: /* Empty the keyboard buffer before waiting for input */
- movb $0x01, %ah
- int $0x16
- jz 2f
- xorw %ax, %ax
- int $0x16
- jmp 1b
-2: /* Wait for a key press */
- movw $ROM_BANNER_TIMEOUT, %cx
-3: decw %cx
- js 99f /* Exit with ZF clear */
- /* Wait for timer tick to be updated */
- call wait_for_tick
- /* Check to see if a key was pressed */
- movb $0x01, %ah
- int $0x16
- jz 3b
- /* Check to see if key was the specified key */
- andb %bh, %al
- cmpb %al, %bl
- je 99f /* Exit with ZF set */
- /* Not the specified key: remove from buffer and stop waiting */
- pushfw
- xorw %ax, %ax
- int $0x16
- popfw /* Exit with ZF clear */
-99: /* Restore registers and return */
- popw %ax
- popw %cx
- ret
- .size wait_for_key, . - wait_for_key
-
-/* Wait for timer tick
- *
- * Used by wait_for_key
- */
-wait_for_tick:
- pushl %eax
- pushw %fs
- movw $0x40, %ax
- movw %ax, %fs
- movl %fs:(0x6c), %eax
-1: pushf
- sti
- hlt
- popf
- cmpl %fs:(0x6c), %eax
- je 1b
- popw %fs
- popl %eax
- ret
- .size wait_for_tick, . - wait_for_tick
diff --git a/gpxe/src/arch/i386/prefix/undiloader.S b/gpxe/src/arch/i386/prefix/undiloader.S
deleted file mode 100644
index 36c1bef3..00000000
--- a/gpxe/src/arch/i386/prefix/undiloader.S
+++ /dev/null
@@ -1,49 +0,0 @@
- .text
- .code16
- .arch i386
- .section ".prefix", "ax", @progbits
-
-/* UNDI loader
- *
- * Called by an external program to load our PXE stack.
- */
- .globl undiloader
-undiloader:
- /* Save registers */
- pushl %esi
- pushl %edi
- pushw %ds
- pushw %es
- pushw %bx
- /* ROM segment address to %ds */
- pushw %cs
- popw %ds
- /* UNDI loader parameter structure address into %es:%di */
- movw %sp, %bx
- movw %ss:18(%bx), %di
- movw %ss:20(%bx), %es
- /* Install to specified real-mode addresses */
- pushw %di
- movw %es:12(%di), %bx
- movw %es:14(%di), %ax
- movl image_source, %esi
- movl decompress_to, %edi
- call install_prealloc
- popw %di
- /* Call UNDI loader C code */
- pushl $pxe_loader_call
- pushw %cs
- pushw $1f
- pushw %ax
- pushw $prot_call
- lret
-1: popw %bx /* discard */
- popw %bx /* discard */
- /* Restore registers and return */
- popw %bx
- popw %es
- popw %ds
- popl %edi
- popl %esi
- lret
- .size undiloader, . - undiloader
diff --git a/gpxe/src/arch/i386/prefix/unnrv2b.S b/gpxe/src/arch/i386/prefix/unnrv2b.S
deleted file mode 100644
index f5724c13..00000000
--- a/gpxe/src/arch/i386/prefix/unnrv2b.S
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
- *
- * This file 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 (at your option) any later version.
- *
- * Originally this code was part of ucl the data compression library
- * for upx the ``Ultimate Packer of eXecutables''.
- *
- * - Converted to gas assembly, and refitted to work with etherboot.
- * Eric Biederman 20 Aug 2002
- *
- * - Structure modified to be a subroutine call rather than an
- * executable prefix.
- * Michael Brown 30 Mar 2004
- *
- * - Modified to be compilable as either 16-bit or 32-bit code.
- * Michael Brown 9 Mar 2005
- */
-
-FILE_LICENCE ( GPL2_OR_LATER )
-
-/****************************************************************************
- * This file provides the decompress() and decompress16() functions
- * which can be called in order to decompress an image compressed with
- * the nrv2b utility in src/util.
- *
- * These functions are designed to be called by the prefix. They are
- * position-independent code.
- *
- * The same basic assembly code is used to compile both
- * decompress() and decompress16().
- ****************************************************************************
- */
-
- .text
- .arch i386
- .section ".prefix.lib", "ax", @progbits
-
-#ifdef CODE16
-/****************************************************************************
- * decompress16 (real-mode near call, position independent)
- *
- * Decompress data in 16-bit mode
- *
- * Parameters (passed via registers):
- * %ds:%esi - Start of compressed input data
- * %es:%edi - Start of output buffer
- * Returns:
- * %ds:%esi - End of compressed input data
- * %es:%edi - End of decompressed output data
- * All other registers are preserved
- *
- * NOTE: It would be possible to build a smaller version of the
- * decompression code for -DKEEP_IT_REAL by using
- * #define REG(x) x
- * to use 16-bit registers where possible. This would impose limits
- * that the compressed data size must be in the range [1,65533-%si]
- * and the uncompressed data size must be in the range [1,65536-%di]
- * (where %si and %di are the input values for those registers). Note
- * particularly that the lower limit is 1, not 0, and that the upper
- * limit on the input (compressed) data really is 65533, since the
- * algorithm may read up to three bytes beyond the end of the input
- * data, since it reads dwords.
- ****************************************************************************
- */
-
-#define REG(x) e ## x
-#define ADDR32 addr32
-
- .code16
- .globl decompress16
-decompress16:
-
-#else /* CODE16 */
-
-/****************************************************************************
- * decompress (32-bit protected-mode near call, position independent)
- *
- * Parameters (passed via registers):
- * %ds:%esi - Start of compressed input data
- * %es:%edi - Start of output buffer
- * Returns:
- * %ds:%esi - End of compressed input data
- * %es:%edi - End of decompressed output data
- * All other registers are preserved
- ****************************************************************************
- */
-
-#define REG(x) e ## x
-#define ADDR32
-
- .code32
- .globl decompress
-decompress:
-
-#endif /* CODE16 */
-
-#define xAX REG(ax)
-#define xCX REG(cx)
-#define xBP REG(bp)
-#define xSI REG(si)
-#define xDI REG(di)
-
- /* Save registers */
- push %xAX
- pushl %ebx
- push %xCX
- push %xBP
- /* Do the decompression */
- cld
- xor %xBP, %xBP
- dec %xBP /* last_m_off = -1 */
- jmp dcl1_n2b
-
-decompr_literals_n2b:
- ADDR32 movsb
-decompr_loop_n2b:
- addl %ebx, %ebx
- jnz dcl2_n2b
-dcl1_n2b:
- call getbit32
-dcl2_n2b:
- jc decompr_literals_n2b
- xor %xAX, %xAX
- inc %xAX /* m_off = 1 */
-loop1_n2b:
- call getbit1
- adc %xAX, %xAX /* m_off = m_off*2 + getbit() */
- call getbit1
- jnc loop1_n2b /* while(!getbit()) */
- sub $3, %xAX
- jb decompr_ebpeax_n2b /* if (m_off == 2) goto decompr_ebpeax_n2b ? */
- shl $8, %xAX
- ADDR32 movb (%xSI), %al /* m_off = (m_off - 3)*256 + src[ilen++] */
- inc %xSI
- xor $-1, %xAX
- jz decompr_end_n2b /* if (m_off == 0xffffffff) goto decomp_end_n2b */
- mov %xAX, %xBP /* last_m_off = m_off ?*/
-decompr_ebpeax_n2b:
- xor %xCX, %xCX
- call getbit1
- adc %xCX, %xCX /* m_len = getbit() */
- call getbit1
- adc %xCX, %xCX /* m_len = m_len*2 + getbit()) */
- jnz decompr_got_mlen_n2b /* if (m_len == 0) goto decompr_got_mlen_n2b */
- inc %xCX /* m_len++ */
-loop2_n2b:
- call getbit1
- adc %xCX, %xCX /* m_len = m_len*2 + getbit() */
- call getbit1
- jnc loop2_n2b /* while(!getbit()) */
- inc %xCX
- inc %xCX /* m_len += 2 */
-decompr_got_mlen_n2b:
- cmp $-0xd00, %xBP
- adc $1, %xCX /* m_len = m_len + 1 + (last_m_off > 0xd00) */
- push %xSI
- ADDR32 lea (%xBP,%xDI), %xSI /* m_pos = dst + olen + -m_off */
- rep
- es ADDR32 movsb /* dst[olen++] = *m_pos++ while(m_len > 0) */
- pop %xSI
- jmp decompr_loop_n2b
-
-
-getbit1:
- addl %ebx, %ebx
- jnz 1f
-getbit32:
- ADDR32 movl (%xSI), %ebx
- sub $-4, %xSI /* sets carry flag */
- adcl %ebx, %ebx
-1:
- ret
-
-decompr_end_n2b:
- /* Restore registers and return */
- pop %xBP
- pop %xCX
- popl %ebx
- pop %xAX
- ret
diff --git a/gpxe/src/arch/i386/prefix/unnrv2b16.S b/gpxe/src/arch/i386/prefix/unnrv2b16.S
deleted file mode 100644
index b24c2846..00000000
--- a/gpxe/src/arch/i386/prefix/unnrv2b16.S
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * 16-bit version of the decompressor
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER )
-
-#define CODE16
-#include "unnrv2b.S"
diff --git a/gpxe/src/arch/i386/prefix/usbdisk.S b/gpxe/src/arch/i386/prefix/usbdisk.S
deleted file mode 100644
index fa7d1956..00000000
--- a/gpxe/src/arch/i386/prefix/usbdisk.S
+++ /dev/null
@@ -1,23 +0,0 @@
- .text
- .arch i386
- .section ".prefix", "awx", @progbits
- .code16
- .org 0
-
-#include "mbr.S"
-
-/* Partition table: ZIP-compatible partition 4, 64 heads, 32 sectors/track */
- .org 446
- .space 16
- .space 16
- .space 16
- .byte 0x80, 0x01, 0x01, 0x00
- .byte 0xeb, 0x3f, 0x20, 0x01
- .long 0x00000020
- .long 0x00000fe0
-
- .org 510
- .byte 0x55, 0xaa
-
-/* Skip to start of partition */
- .org 32 * 512
diff --git a/gpxe/src/arch/i386/prefix/xromprefix.S b/gpxe/src/arch/i386/prefix/xromprefix.S
deleted file mode 100644
index d7c861f5..00000000
--- a/gpxe/src/arch/i386/prefix/xromprefix.S
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * ROM prefix that loads the bulk of the ROM using direct PCI accesses,
- * so as not to take up much option ROM space on PCI <3.0 systems.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER )
-
-#define LOAD_ROM_FROM_PCI
-#include "romprefix.S"