summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S')
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S969
1 files changed, 969 insertions, 0 deletions
diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S
new file mode 100644
index 000000000..7c1ece791
--- /dev/null
+++ b/qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S
@@ -0,0 +1,969 @@
+/*
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER )
+
+ .arch i386
+
+/* Image compression enabled */
+#define COMPRESS 1
+
+/* Protected mode flag */
+#define CR0_PE 1
+
+/* Allow for DBG()-style messages within libprefix */
+#ifdef NDEBUG
+ .macro progress message
+ .endm
+#else
+ .macro progress message
+ pushfl
+ pushw %ds
+ pushw %si
+ pushw %di
+ pushw %cs
+ popw %ds
+ xorw %di, %di
+ movw $progress_\@, %si
+ call print_message
+ popw %di
+ popw %si
+ popw %ds
+ popfl
+ .section ".prefix.data", "aw", @progbits
+progress_\@:
+ .asciz "\message"
+ .size progress_\@, . - progress_\@
+ .previous
+ .endm
+#endif
+
+/*****************************************************************************
+ * 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 space
+ *
+ * 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_space
+print_space:
+ /* Preserve registers */
+ pushw %ax
+ /* Print space */
+ movb $( ' ' ), %al
+ call print_character
+ /* Restore registers and return */
+ popw %ax
+ ret
+ .size print_space, . - print_space
+
+/*****************************************************************************
+ * 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 */
+ movw $79, %cx
+1: call print_space
+ loop 1b
+ /* Print CR */
+ call print_character
+ /* Restore registers and return */
+ popw %cx
+ popw %ax
+ ret
+ .size print_kill_line, . - print_kill_line
+
+/****************************************************************************
+ * copy_bytes
+ *
+ * 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
+
+/****************************************************************************
+ * zero_bytes
+ *
+ * Zero 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
+zero_bytes:
+ pushl %ecx
+ pushw %ax
+ xorw %ax, %ax
+ rep addr32 stosb
+ popw %ax
+ popl %ecx
+ ret
+ .size zero_bytes, . - zero_bytes
+
+/****************************************************************************
+ * process_bytes
+ *
+ * Call memcpy()-like function
+ *
+ * Parameters:
+ * %esi : source physical address
+ * %edi : destination physical address
+ * %ecx : length
+ * %bx : memcpy()-like function to call, passing parameters:
+ * %ds:esi : source address
+ * %es:edi : destination address
+ * %ecx : length
+ * and returning:
+ * %ds:esi : next source address
+ * %es:edi : next destination address
+ * Returns:
+ * %esi : next source physical address
+ * %edi : next destination physical address
+ * Corrupts:
+ * None
+ ****************************************************************************
+ */
+ .section ".prefix.lib", "awx", @progbits
+ .code16
+process_bytes:
+
+#ifndef KEEP_IT_REAL
+
+ /* Preserve registers */
+ pushl %eax
+ pushl %ebp
+
+ /* Construct GDT on stack (since .prefix may not be writable) */
+ .equ PM_DS, 0x18 /* Flat data segment */
+ pushl $0x00cf9300
+ pushl $0x0000ffff
+ .equ PM_SS, 0x10 /* Stack segment based at %ss:0000 */
+ pushl $0x008f0930
+ pushw %ss
+ pushw $0xffff
+ .equ PM_CS, 0x08 /* Code segment based at %cs:0000 */
+ pushl $0x008f09b0
+ pushw %cs
+ pushw $0xffff
+ pushl $0 /* Base and length */
+ pushw %ss
+ pushw $0x1f
+ movzwl %sp, %ebp
+ shll $4, 0x02(%bp)
+ addl %ebp, 0x02(%bp)
+ shll $4, 0x0a(%bp)
+ shll $4, 0x12(%bp)
+ subw $8, %sp
+ sgdt -8(%bp)
+
+ /* Switch to protected mode */
+ pushw %gs
+ pushw %fs
+ pushw %es
+ pushw %ds
+ pushw %ss
+ pushw %cs
+ pushw $2f
+ cli
+ data32 lgdt (%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
+
+ /* Call memcpy()-like function */
+ call *%bx
+
+ /* Return to (flat) real mode */
+ movl %cr0, %eax
+ andb $0!CR0_PE, %al
+ movl %eax, %cr0
+ lret
+2: /* lret will ljmp to here */
+ popw %ss
+ popw %ds
+ popw %es
+ popw %fs
+ popw %gs
+
+ /* Restore GDT */
+ data32 lgdt -8(%bp)
+ addw $( 8 /* saved GDT */ + ( PM_DS + 8 ) /* GDT on stack */ ), %sp
+
+ /* Restore registers and return */
+ popl %ebp
+ popl %eax
+ ret
+
+#else /* KEEP_IT_REAL */
+
+ /* Preserve registers */
+ pushl %eax
+ pushw %ds
+ pushw %es
+
+ /* Convert %esi and %edi to %ds:esi and %es:edi */
+ shrl $4, %esi
+ movw %si, %ds
+ xorw %si, %si
+ shll $4, %esi
+ shrl $4, %edi
+ movw %di, %es
+ xorw %di, %di
+ shll $4, %edi
+
+ /* Call memcpy()-like function */
+ call *%bx
+
+ /* Convert %ds:esi and %es:edi back to physical addresses */
+ xorl %eax, %eax
+ movw %ds, %cx
+ shll $4, %eax
+ addl %eax, %esi
+ xorl %eax, %eax
+ movw %es, %cx
+ shll $4, %eax
+ addl %eax, %edi
+
+ /* Restore registers and return */
+ popw %es
+ popw %ds
+ popl %eax
+ ret
+
+#endif /* KEEP_IT_REAL */
+
+ .size process_bytes, . - process_bytes
+
+/****************************************************************************
+ * install_block
+ *
+ * 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)
+ * %edi : next destination physical address (will be a multiple of 16)
+ * Corrupts:
+ * none
+ ****************************************************************************
+ */
+ .section ".prefix.lib", "awx", @progbits
+ .code16
+install_block:
+ /* Preserve registers */
+ pushl %ecx
+ pushw %bx
+
+ /* Decompress (or copy) source to destination */
+#if COMPRESS
+ movw $decompress16, %bx
+#else
+ movw $copy_bytes, %bx
+#endif
+ call process_bytes
+
+ /* Zero .bss portion */
+ negl %ecx
+ addl %edx, %ecx
+ movw $zero_bytes, %bx
+ call process_bytes
+
+ /* Round up %esi and %edi to start of next blocks */
+ addl $0xf, %esi
+ andl $~0xf, %esi
+ addl $0xf, %edi
+ andl $~0xf, %edi
+
+ /* Restore registers and return */
+ popw %bx
+ popl %ecx
+ ret
+ .size install_block, . - install_block
+
+/****************************************************************************
+ * alloc_basemem
+ *
+ * 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. Round down to ensure
+ * low bits are zero, to speed up mode transitions under KVM.
+ */
+ subw $_text16_memsz_pgh, %ax
+ andb $~0x03, %al
+ 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
+ *
+ * Free space allocated with alloc_basemem.
+ *
+ * Parameters:
+ * none (.text16 segment address is implicit in %cs)
+ * Returns:
+ * %ax : 0 if successfully freed
+ * Corrupts:
+ * none
+ ****************************************************************************
+ */
+ .section ".text16", "ax", @progbits
+ .code16
+ .globl free_basemem
+free_basemem:
+ /* Preserve registers */
+ pushw %fs
+ pushw %ax
+
+ /* Check FBMS counter */
+ movw %cs, %ax
+ shrw $6, %ax
+ pushw $0x40
+ popw %fs
+ cmpw %ax, %fs:0x13
+ jne 1f
+
+ /* Check hooked interrupt count */
+ cmpw $0, %cs:hooked_bios_interrupts
+ jne 1f
+
+ /* OK to free memory */
+ movw %cs, %ax
+ 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 %ax
+ 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
+ *
+ * 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:
+ progress "install:\n"
+ /* Preserve registers */
+ pushl %esi
+ pushl %edi
+ pushl %ebp
+ /* Allocate space for .text16 and .data16 */
+ call alloc_basemem
+ /* Image source = %cs:0000 */
+ xorl %esi, %esi
+ /* Image destination = default */
+ xorl %edi, %edi
+ /* Allow arbitrary relocation */
+ orl $0xffffffff, %ebp
+ /* Install text and data segments */
+ call install_prealloc
+ /* Restore registers and return */
+ popl %ebp
+ popl %edi
+ popl %esi
+ ret
+ .size install, . - install
+
+/****************************************************************************
+ * install_prealloc
+ *
+ * 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 (or zero for default)
+ * %ebp : Maximum end address for relocation
+ * - 0xffffffff for no maximum
+ * - 0x00000000 to inhibit use of INT 15,e820 and INT 15,e801
+ * Corrupts:
+ * none
+ ****************************************************************************
+ */
+ .section ".prefix.lib", "awx", @progbits
+ .code16
+ .globl install_prealloc
+install_prealloc:
+ progress "install_prealloc:\n"
+ /* Save registers */
+ pushal
+ pushw %ds
+ pushw %es
+ cld /* Sanity: clear the direction flag asap */
+
+ /* Set up %ds for (read-only) access to .prefix */
+ pushw %cs
+ popw %ds
+
+ /* Save decompression temporary area physical address */
+ pushl %edi
+
+ /* Install .text16.early and calculate %ecx as offset to next block */
+ progress " .text16.early\n"
+ pushl %esi
+ xorl %esi, %esi
+ movw %cs, %si
+ shll $4, %esi
+ pushl %esi /* Save original %cs:0000 */
+ addl $_text16_early_lma, %esi
+ movzwl %ax, %edi
+ shll $4, %edi
+ movl $_text16_early_filesz, %ecx
+ movl $_text16_early_memsz, %edx
+ call install_block /* .text16.early */
+ popl %ecx /* Calculate offset to next block */
+ subl %esi, %ecx
+ negl %ecx
+ popl %esi
+
+#ifndef KEEP_IT_REAL
+ /* Access high memory by enabling the A20 gate. (We will
+ * already have 4GB segment limits as a result of calling
+ * install_block.)
+ */
+ progress " access_highmem\n"
+ pushw %cs
+ pushw $1f
+ pushw %ax
+ pushw $access_highmem
+ lret
+1: /* Die if we could not access high memory */
+ jnc 3f
+ movw $a20_death_message, %si
+ xorw %di, %di
+ call print_message
+2: jmp 2b
+ .section ".prefix.data", "aw", @progbits
+a20_death_message:
+ .asciz "\nHigh memory inaccessible - cannot continue\n"
+ .size a20_death_message, . - a20_death_message
+ .previous
+3:
+#endif
+
+ /* Open payload (which may not yet be in memory) */
+ progress " open_payload\n"
+ pushw %cs
+ pushw $1f
+ pushw %ax
+ pushw $open_payload
+ lret
+1: /* Die if we could not access the payload */
+ jnc 3f
+ xorw %di, %di
+ movl %esi, %eax
+ call print_hex_dword
+ call print_space
+ movl %ecx, %eax
+ call print_hex_dword
+ movw $payload_death_message, %si
+ call print_message
+2: /* Halt system */
+ cli
+ hlt
+ jmp 2b
+ .section ".prefix.data", "aw", @progbits
+payload_death_message:
+ .asciz "\nPayload inaccessible - cannot continue\n"
+ .size payload_death_message, . - payload_death_message
+ .previous
+3:
+
+ /* Calculate physical address of payload (i.e. first source) */
+ testl %esi, %esi
+ jnz 1f
+ movw %cs, %si
+ shll $4, %esi
+1: addl %ecx, %esi
+
+ /* Install .text16.late and .data16 */
+ progress " .text16.late\n"
+ movl $_text16_late_filesz, %ecx
+ movl $_text16_late_memsz, %edx
+ call install_block /* .text16.late */
+ progress " .data16\n"
+ movzwl %bx, %edi
+ shll $4, %edi
+ movl $_data16_filesz, %ecx
+ movl $_data16_memsz, %edx
+ call install_block /* .data16 */
+
+ /* Set up %ds for access to .data16 */
+ movw %bx, %ds
+
+ /* Restore decompression temporary area physical address */
+ popl %edi
+
+#ifdef KEEP_IT_REAL
+ /* Initialise libkir */
+ movw %ax, (init_libkir_vector+2)
+ lcall *init_libkir_vector
+#else
+ /* Find a suitable decompression temporary area, if none specified */
+ pushl %eax
+ testl %edi, %edi
+ jnz 1f
+ /* Use INT 15,88 to find the highest available address via INT
+ * 15,88. This limits us to around 64MB, which should avoid
+ * all of the POST-time memory map failure modes.
+ */
+ movb $0x88, %ah
+ int $0x15
+ movw %ax, %di
+ addl $0x400, %edi
+ subl $_textdata_memsz_kb, %edi
+ shll $10, %edi
+ /* Sanity check: if we have ended up below 1MB, use 1MB */
+ cmpl $0x100000, %edi
+ jae 1f
+ movl $0x100000, %edi
+1: popl %eax
+
+ /* Install .text and .data to temporary area in high memory,
+ * prior to reading the E820 memory map and relocating
+ * properly.
+ */
+ progress " .textdata\n"
+ pushl %edi
+ movl $_textdata_filesz, %ecx
+ movl $_textdata_memsz, %edx
+ call install_block
+ popl %edi
+
+ /* Initialise librm at current location */
+ progress " init_librm\n"
+ movw %ax, (init_librm_vector+2)
+ lcall *init_librm_vector
+
+ /* Inhibit INT 15,e820 and INT 15,e801 if applicable */
+ testl %ebp, %ebp
+ jnz 1f
+ incb memmap_post
+ decl %ebp
+1:
+
+ /* 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.
+ */
+ progress " relocate\n"
+ movw %ax, (prot_call_vector+2)
+ pushl $relocate
+ lcall *prot_call_vector
+ popl %edx /* discard */
+
+ /* Copy code to new location */
+ progress " copy\n"
+ pushl %edi
+ pushw %bx
+ movw $copy_bytes, %bx
+ call process_bytes
+ popw %bx
+ popl %edi
+
+ /* Initialise librm at new location */
+ progress " init_librm\n"
+ lcall *init_librm_vector
+#endif
+
+ /* Close access to payload */
+ progress " close_payload\n"
+ movw %ax, (close_payload_vector+2)
+ lcall *close_payload_vector
+
+ /* Restore registers */
+ popw %es
+ popw %ds
+ popal
+ ret
+ .size install_prealloc, . - install_prealloc
+
+ /* Vectors for far calls to .text16 functions. Must be in
+ * .data16, since .prefix may not be writable.
+ */
+ .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
+close_payload_vector:
+ .word close_payload
+ .word 0
+ .size close_payload_vector, . - close_payload_vector
+
+ /* Dummy routines to open and close payload */
+ .section ".text16.early.data", "aw", @progbits
+ .weak open_payload
+ .weak close_payload
+open_payload:
+close_payload:
+ clc
+ lret
+ .size open_payload, . - open_payload
+ .size close_payload, . - close_payload
+
+/****************************************************************************
+ * uninstall
+ *
+ * Uninstall all text and data segments.
+ *
+ * Parameters:
+ * none (.text16 segment address is implicit in %cs)
+ * 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
+#define PACK_OR_COPY "PACK"
+#else
+#define PACK_OR_COPY "COPY"
+#endif
+ .section ".zinfo", "a", @progbits
+ .ascii "COPY"
+ .long _prefix_lma
+ .long _prefix_filesz
+ .long _max_align
+ .ascii PACK_OR_COPY
+ .long _text16_early_lma
+ .long _text16_early_filesz
+ .long _max_align
+ .ascii "PAYL"
+ .long 0
+ .long 0
+ .long _payload_align
+ .ascii "COPY"
+ .long _pprefix_lma
+ .long _pprefix_filesz
+ .long _max_align
+ .ascii PACK_OR_COPY
+ .long _text16_late_lma
+ .long _text16_late_filesz
+ .long _max_align
+ .ascii PACK_OR_COPY
+ .long _data16_lma
+ .long _data16_filesz
+ .long _max_align
+ .ascii PACK_OR_COPY
+ .long _textdata_lma
+ .long _textdata_filesz
+ .long _max_align
+
+ .weak _payload_align
+ .equ _payload_align, 1