summaryrefslogtreecommitdiffstats
path: root/src/arch/i386/prefix/libprefix.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/i386/prefix/libprefix.S')
-rw-r--r--src/arch/i386/prefix/libprefix.S88
1 files changed, 58 insertions, 30 deletions
diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S
index 12cf9184d..406dac393 100644
--- a/src/arch/i386/prefix/libprefix.S
+++ b/src/arch/i386/prefix/libprefix.S
@@ -17,6 +17,10 @@
*
*/
+ .arch i386
+ .section ".prefix.lib", "awx", @progbits
+ .section ".data16", "aw", @progbits
+
/**
* High memory temporary load address
*
@@ -27,25 +31,18 @@
* 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 there is at least one commercial
- * PXE ROM ("Broadcom UNDI, PXE-2.1 (build 082) v2.0.4") which stores
- * data required by the UNDI ROM loader (yes, the ROM loader; that's
- * the component which should be impossible to damage short of
- * screwing with the MMU) around the 2MB mark. Sadly, this is not a
- * joke.
- *
+ * 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.
*/
-#define HIGHMEM_LOADPOINT ( 4 << 20 )
+ .globl HIGHMEM_LOADPOINT
+ .equ HIGHMEM_LOADPOINT, ( 4 << 20 )
/* Image compression enabled */
#define COMPRESS 1
#define CR0_PE 1
- .arch i386
- .section ".prefix.lib", "awx", @progbits
- .section ".data16", "aw", @progbits
-
/****************************************************************************
* pm_call (real-mode near call)
*
@@ -223,12 +220,15 @@ copy_bytes:
* Returns:
* %ds:esi : next source address (will be a multiple of 16)
* Corrupts:
- * %edi, %ecx, %edx
+ * %ecx, %edx
****************************************************************************
*/
.section ".prefix.lib"
.code16
install_block:
+ /* Preserve registers */
+ pushl %edi
+
#if COMPRESS
/* Decompress source to destination */
call decompress16
@@ -249,6 +249,8 @@ install_block:
addl $0xf, %esi
andl $~0xf, %esi
+ /* Restore registers and return */
+ popl %edi
ret
.size install_block, . - install_block
@@ -270,6 +272,7 @@ install_block:
*/
.section ".prefix.lib"
.code16
+ .globl alloc_basemem
alloc_basemem:
/* FBMS => %ax as segment address */
movw $0x40, %ax
@@ -308,13 +311,14 @@ alloc_basemem:
* Returns:
* %esi : next source physical address (will be a multiple of 16)
* Corrupts:
- * %edi, %ecx, %edx
+ * %ecx, %edx
****************************************************************************
*/
.section ".prefix.lib"
.code16
install_basemem:
/* Preserve registers */
+ pushl %edi
pushw %ds
/* Preserve original %esi */
@@ -335,6 +339,7 @@ install_basemem:
/* Restore registers */
popw %ds
+ popl %edi
ret
.size install_basemem, . - install_basemem
@@ -351,7 +356,7 @@ install_basemem:
* Returns:
* %esi : next source physical address (will be a multiple of 16)
* Corrupts:
- * %edi, %ecx, %edx
+ * %ecx, %edx
****************************************************************************
*/
@@ -376,17 +381,14 @@ install_highmem:
/****************************************************************************
* install (real-mode near call)
- * install_prealloc (real-mode near call)
*
* Install all text and data segments.
*
* Parameters:
- * %ax : .text16 segment address (install_prealloc only)
- * %bx : .data16 segment address (install_prealloc only)
+ * none
* Returns:
- * %ax : .text16 segment address
- * %bx : .data16 segment address
- * %edi : .text physical address (if applicable)
+ * %ax : .text16 segment address
+ * %bx : .data16 segment address
* Corrupts:
* none
****************************************************************************
@@ -395,26 +397,55 @@ install_highmem:
.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"
+ .code16
.globl install_prealloc
install_prealloc:
/* Save registers */
+ pushal
pushw %ds
pushw %es
- pushl %esi
- pushl %ecx
- pushl %edx
/* Sanity: clear the direction flag asap */
cld
/* Calculate physical address of payload (i.e. first source) */
- xorl %esi, %esi
+ testl %esi, %esi
+ jnz 1f
movw %cs, %si
shll $4, %esi
- addl $_payload_offset, %esi
+1: addl $_payload_offset, %esi
/* Install .text16 */
movw %ax, %es
@@ -440,7 +471,6 @@ install_prealloc:
* prior to reading the E820 memory map and relocating
* properly.
*/
- movl $HIGHMEM_LOADPOINT, %edi
movl $_textdata_progbits_size, %ecx
movl $_textdata_size, %edx
pushl %edi
@@ -473,11 +503,9 @@ install_prealloc:
#endif
/* Restore registers */
- popl %edx
- popl %ecx
- popl %esi
popw %es
popw %ds
+ popal
ret
.size install_prealloc, . - install_prealloc