diff options
Diffstat (limited to 'qemu/roms/ipxe/src/arch/i386/prefix')
21 files changed, 1085 insertions, 228 deletions
diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/bootpart.S b/qemu/roms/ipxe/src/arch/i386/prefix/bootpart.S index 968da1a38..6d0c6034a 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/bootpart.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/bootpart.S @@ -1,4 +1,4 @@ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) #define BOOT_SEG 0x07c0 #define EXEC_SEG 0x0100 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/exeprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/exeprefix.S index cb61287d3..5c648d51d 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/exeprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/exeprefix.S @@ -16,9 +16,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + * */ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) /* Initial temporary stack size */ #define EXE_STACK_SIZE 0x400 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/hdprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/hdprefix.S index 876bfe1be..1d012d80b 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/hdprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/hdprefix.S @@ -1,4 +1,4 @@ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) .text .arch i386 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/isaromprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/isaromprefix.S index e28208089..fb49819ee 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/isaromprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/isaromprefix.S @@ -16,9 +16,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + * */ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) #define BUSTYPE "ISAR" #define _rom_start _isarom_start diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S index 27ed231e7..6e43cd26a 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S @@ -5,12 +5,10 @@ ***************************************************************************** */ -FILE_LICENCE ( GPL2_OR_LATER ) - -/* Since we have the whole stack, we can use cached DHCP information */ -REQUIRE_OBJECT ( pxeparent_dhcp ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) /* Provide the PXENV_FILE_EXIT_HOOK API call */ +REQUIRING_SYMBOL ( _kkkpxe_start ) REQUIRE_OBJECT ( pxe_exit_hook ) #define PXELOADER_KEEP_UNDI diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S index d177d7d62..3c17dbdb1 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S @@ -3,10 +3,7 @@ ***************************************************************************** */ -FILE_LICENCE ( GPL2_OR_LATER ) - -/* Since we have the whole stack, we can use cached DHCP information */ -REQUEST_OBJECT ( pxeparent_dhcp ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) #define PXELOADER_KEEP_UNDI #define PXELOADER_KEEP_PXE diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/kpxeprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/kpxeprefix.S index c75608172..200006d83 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/kpxeprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/kpxeprefix.S @@ -3,7 +3,7 @@ ***************************************************************************** */ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) #define PXELOADER_KEEP_UNDI #define _pxe_start _kpxe_start diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S index 7c1ece791..7d5c1ed53 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S @@ -16,9 +16,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + * */ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) .arch i386 @@ -296,11 +300,9 @@ copy_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 @@ -396,8 +398,10 @@ process_bytes: movw %ax, %fs movw %ax, %gs +#ifdef NDEBUG /* Call memcpy()-like function */ call *%bx +#endif /* Return to (flat) real mode */ movl %cr0, %eax @@ -411,6 +415,20 @@ process_bytes: popw %fs popw %gs +#ifndef NDEBUG + /* Call memcpy()-like function in flat real mode (to allow for + * debug output via INT 10). + */ + pushw %ds + pushw %es + xorw %ax, %ax + movw %ax, %ds + movw %ax, %es + call *%bx + popw %es + popw %ds +#endif + /* Restore GDT */ data32 lgdt -8(%bp) addw $( 8 /* saved GDT */ + ( PM_DS + 8 ) /* GDT on stack */ ), %sp @@ -442,11 +460,11 @@ process_bytes: /* Convert %ds:esi and %es:edi back to physical addresses */ xorl %eax, %eax - movw %ds, %cx + movw %ds, %ax shll $4, %eax addl %eax, %esi xorl %eax, %eax - movw %es, %cx + movw %es, %ax shll $4, %eax addl %eax, %edi @@ -678,12 +696,21 @@ install: .globl install_prealloc install_prealloc: progress "install_prealloc:\n" - /* Save registers */ + /* Save registers on external stack */ pushal pushw %ds pushw %es cld /* Sanity: clear the direction flag asap */ + /* Switch to temporary stack in .bss16 */ + pushw %ss + popw %ds + movl %esp, %ecx + movw %bx, %ss + movl $_data16_memsz, %esp + pushw %ds + pushl %ecx + /* Set up %ds for (read-only) access to .prefix */ pushw %cs popw %ds @@ -710,6 +737,7 @@ install_prealloc: 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.) @@ -778,7 +806,7 @@ payload_death_message: movzwl %bx, %edi shll $4, %edi movl $_data16_filesz, %ecx - movl $_data16_memsz, %edx + movl $_data16_filesz, %edx /* do not zero our temporary stack */ call install_block /* .data16 */ /* Set up %ds for access to .data16 */ @@ -787,11 +815,8 @@ payload_death_message: /* 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 +#ifndef KEEP_IT_REAL + /* Find a suitable decompression temporary area, if none specified */ pushl %eax testl %edi, %edi @@ -823,6 +848,22 @@ payload_death_message: call install_block popl %edi +#endif /* KEEP_IT_REAL */ + + /* Switch back to original stack and zero .bss16 */ + addr32 lss %ss:(%esp), %esp + pushl %edi + pushw %es + movw %bx, %es + movl $_data16_filesz, %edi + movl $_data16_memsz, %ecx + subl %edi, %ecx + call zero_bytes + popw %es + popl %edi + +#ifndef KEEP_IT_REAL + /* Initialise librm at current location */ progress " init_librm\n" movw %ax, (init_librm_vector+2) @@ -834,7 +875,6 @@ payload_death_message: 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. @@ -857,7 +897,14 @@ payload_death_message: /* Initialise librm at new location */ progress " init_librm\n" lcall *init_librm_vector -#endif + +#else /* KEEP_IT_REAL */ + + /* Initialise libkir */ + movw %ax, (init_libkir_vector+2) + lcall *init_libkir_vector + +#endif /* KEEP_IT_REAL */ /* Close access to payload */ progress " close_payload\n" diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/lkrnprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/lkrnprefix.S index 259bc6ba5..64135e14b 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/lkrnprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/lkrnprefix.S @@ -1,4 +1,4 @@ -FILE_LICENCE ( GPL_ANY ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) #define BZI_LOAD_HIGH_ADDR 0x100000 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/mbr.S b/qemu/roms/ipxe/src/arch/i386/prefix/mbr.S index adfe20410..a1e237de8 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/mbr.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/mbr.S @@ -1,3 +1,5 @@ +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) + .text .arch i386 .section ".prefix", "awx", @progbits diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/mromprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/mromprefix.S index 4c94457c2..b636b92af 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/mromprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/mromprefix.S @@ -16,9 +16,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + * */ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) #define PCIBIOS_READ_CONFIG_WORD 0xb109 #define PCIBIOS_READ_CONFIG_DWORD 0xb10a @@ -463,6 +467,7 @@ pci_set_mem_access: .org 0x00 mromheader: .word 0xaa55 /* BIOS extension signature */ + .byte 0x01 /* Dummy size (BIOS bug workaround) */ .org 0x18 .word mpciheader .org 0x1a diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/nbiprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/nbiprefix.S index 06e7df5b7..16c79566c 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/nbiprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/nbiprefix.S @@ -1,3 +1,5 @@ +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) + .text .arch i386 .code16 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/nullprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/nullprefix.S index 032d41e0f..bd0ff339e 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/nullprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/nullprefix.S @@ -1,3 +1,5 @@ +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) + .org 0 .text .arch i386 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/pciromprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/pciromprefix.S index 45ba31f50..5a5a49647 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/pciromprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/pciromprefix.S @@ -16,9 +16,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + * */ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) #define BUSTYPE "PCIR" #define _rom_start _pcirom_start diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/pxeprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/pxeprefix.S index 6e29c7949..465ce4345 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/pxeprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/pxeprefix.S @@ -1,4 +1,4 @@ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) #define PXENV_UNDI_SHUTDOWN 0x0005 #define PXENV_UNDI_GET_NIC_TYPE 0x0012 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/romprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/romprefix.S index 7bc4fe8cd..18dda2b37 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/romprefix.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/romprefix.S @@ -6,9 +6,10 @@ * table so using a noticeable amount of stack space is a no-no. */ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) #include <config/general.h> +#include <config/branding.h> #define PNP_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) ) #define PMM_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'M' << 16 ) + ( 'M' << 24 ) ) @@ -90,7 +91,7 @@ pciheader: .ascii "PCIR" /* Signature */ .word pci_vendor_id /* Vendor identification */ .word pci_device_id /* Device identification */ - .word 0x0000 /* Device list pointer */ + .word ( pci_devlist - pciheader ) /* Device list pointer */ .word pciheader_len /* PCI data structure length */ .byte 0x03 /* PCI data structure revision */ .byte 0x02, 0x00, 0x00 /* Class code */ @@ -106,6 +107,17 @@ pciheader_runtime_length: .equ pciheader_len, . - pciheader .size pciheader, . - pciheader + /* PCI additional device list (filled in by linker) */ + .section ".pci_devlist.00000000", "a", @progbits +pci_devlist: + .previous + .section ".pci_devlist.ffffffff", "a", @progbits +pci_devlist_end: + .short 0x0000 /* List terminator */ + .previous + /* Ensure that terminator is always present */ + .reloc pciheader, RELOC_TYPE_NONE, pci_devlist_end + .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ .ascii ZINFO_TYPE_ADxW .long pciheader_image_length @@ -573,7 +585,7 @@ get_pmm_decompress_to: * 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. + * strings PRODUCT_NAME and PRODUCT_SHORT_NAME in config/branding.h. * * While nothing in the GPL prevents you from removing all references * to iPXE or http://ipxe.org, we prefer you not to do so. @@ -589,7 +601,10 @@ init_message: .ascii "\n" .ascii PRODUCT_NAME .ascii "\n" - .asciz "iPXE (http://ipxe.org)" + .ascii PRODUCT_SHORT_NAME + .ascii " (" + .ascii PRODUCT_URI + .asciz ")" .size init_message, . - init_message .ifeqs BUSTYPE, "PCIR" init_message_pci: @@ -771,7 +786,9 @@ exec: /* Set %ds = %cs */ /* Store PCI bus:dev.fn, if applicable */ .ifeqs BUSTYPE, "PCIR" +#ifdef AUTOBOOT_ROM_FILTER movw %ax, autoboot_busdevfn +#endif /* AUTOBOOT_ROM_FILTER */ .endif /* Call main() */ @@ -870,3 +887,9 @@ wait_for_tick: popl %eax ret .size wait_for_tick, . - wait_for_tick + +/* Drag in objects via _rom_start */ +REQUIRING_SYMBOL ( _rom_start ) + +/* Drag in ROM configuration */ +REQUIRE_OBJECT ( config_romprefix ) diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/undiloader.S b/qemu/roms/ipxe/src/arch/i386/prefix/undiloader.S index 74bb59041..5cace44b7 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/undiloader.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/undiloader.S @@ -1,4 +1,4 @@ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) .text .code16 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/unlzma.S b/qemu/roms/ipxe/src/arch/i386/prefix/unlzma.S new file mode 100644 index 000000000..8d4b3c1a8 --- /dev/null +++ b/qemu/roms/ipxe/src/arch/i386/prefix/unlzma.S @@ -0,0 +1,942 @@ +/* + * Copyright (C) 2015 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 (at your option) 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/**************************************************************************** + * + * This file provides the decompress() and decompress16() functions + * which can be called in order to decompress an LZMA-compressed + * image. The code is modelled on the public-domain "XZ Embedded" + * implementation as used by the Linux kernel. Symbol names are + * chosen to match the XZ Embedded implementation where possible, for + * ease of reference. + * + * This code is optimised for size rather than speed, since the amount + * of data to be decompressed is trivially small by modern standards. + * + * The same basic assembly code is used to compile both decompress() + * and decompress16(). + * + * Note that these functions require large amounts of stack space. + * + **************************************************************************** + */ + + .text + .arch i586 + .section ".prefix.lib", "ax", @progbits + +#ifdef CODE16 +#define ADDR16 +#define ADDR32 addr32 +#define decompress decompress16 + .code16 +#else /* CODE16 */ +#define ADDR16 addr16 +#define ADDR32 + .code32 +#endif /* CODE16 */ + +/**************************************************************************** + * Debugging + **************************************************************************** + * + * This code will usually run in 16-bit protected mode, in which case + * only the 0xe9 debug port (present on some virtual machines) can be + * used. + * + * To debug on real hardware, build with DEBUG=libprefix. This will + * cause this code to be called in flat real mode, and so DEBUG_INT10 + * may be used. + */ + +/* Enable debugging via 0xe9 debug port */ +#define DEBUG_E9 0 + +/* Enable debugging via BIOS INT 10 (works only when in flat real mode) */ +#define DEBUG_INT10 0 + +#if ( DEBUG_E9 || DEBUG_INT10 ) + .macro print_character, reg + pushfl + pushw %ax + pushw %bx + pushw %bp + movb \reg, %al + movw $0x0007, %bx + movb $0x0e, %ah +#if DEBUG_E9 + outb %al, $0xe9 +#endif +#if DEBUG_INT10 + cmpb $('\n'), %al + jne L\@ + int $0x10 + movb $('\r'), %al +L\@: int $0x10 +#endif + popw %bp + popw %bx + popw %ax + popfl + .endm + + .macro print_hex_nibble + pushfl + pushw %ax + cmpb $10, %al + sbb $0x69, %al + das + print_character %al + popw %ax + popfl + .endm + + .macro print_hex_byte, reg + pushfl + pushw %ax + movb \reg, %al + pushw %ax + shrb $4, %al + print_hex_nibble + popw %ax + andb $0x0f, %al + print_hex_nibble + popw %ax + popfl + .endm + + .macro print_hex_word, reg + pushw %ax + movw \reg, %ax + print_hex_byte %ah + print_hex_byte %al + popw %ax + .endm + + .macro print_hex_dword, reg + pushl %eax + movl \reg, %eax + rorl $16, %eax + print_hex_word %ax + rorl $16, %eax + print_hex_word %ax + popl %eax + .endm +#else + .macro print_character, char + .endm + .macro print_hex_byte, reg + .endm + .macro print_hex_word, reg + .endm + .macro print_hex_dword, reg + .endm +#endif + +/**************************************************************************** + * LZMA parameters and data structures + **************************************************************************** + */ + +/* LZMA decompressor states (as used in XZ Embedded) */ +#define STATE_LIT_LIT 0x00 +#define STATE_MATCH_LIT_LIT 0x01 +#define STATE_REP_LIT_LIT 0x02 +#define STATE_SHORTREP_LIT_LIT 0x03 +#define STATE_MATCH_LIT 0x04 +#define STATE_REP_LIT 0x05 +#define STATE_SHORTREP_LIT 0x06 +#define STATE_LIT_MATCH 0x07 +#define STATE_LIT_LONGREP 0x08 +#define STATE_LIT_SHORTREP 0x09 +#define STATE_NONLIT_MATCH 0x0a +#define STATE_NONLIT_REP 0x0b + +/* LZMA maximum decompressor state in which most recent symbol was a literal */ +#define STATE_LIT_MAX 0x06 + +/* LZMA number of literal context bits ("lc=" parameter) */ +#define LZMA_LC 2 + + .struct 0 +lzma_len_dec: +choice: .word 0 +choice2: .word 0 +low: .rept ( 1 << 3 ) + .word 0 + .endr +mid: .rept ( 1 << 3 ) + .word 0 + .endr +high: .rept ( 1 << 8 ) + .word 0 + .endr + .equ sizeof__lzma_len_dec, . - lzma_len_dec + .previous + + .struct 0 +lzma_dec: +out_start: .long 0 +rc_code: .long 0 +rc_range: .long 0 +len: .word 0 +reps: +rep0: .long 0 +rep1: .long 0 +rep2: .long 0 +rep3: .long 0 +probs: +is_match: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +is_rep: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +is_rep0: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +is_rep1: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +is_rep2: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +is_rep0_long: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +dist_slot: .rept ( 4 * ( 1 << 6 ) ) + .word 0 + .endr +dist_special: .rept ( ( 1 << ( 14 / 2 ) ) - 14 ) + .word 0 + .endr +dist_align: .rept ( 1 << 4 ) + .word 0 + .endr +match_len_dec: .space sizeof__lzma_len_dec +rep_len_dec: .space sizeof__lzma_len_dec +literal: .rept ( ( 1 << LZMA_LC ) * 0x300 ) + .word 0 + .endr + .align 4 + .equ sizeof__lzma_dec, . - lzma_dec + .previous + + /* Some binutils versions seem not to handle .struct/.previous */ + .section ".prefix.lib", "ax", @progbits + +/***************************************************************************** + * Normalise range encoder + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * %eax : current range + ***************************************************************************** + */ +rc_normalise: + /* Check if rc_range is less than 1<<24 */ + testb $0xff, (rc_range+3)(%ebp) + jnz 1f + /* If it is, shift in a new byte from the compressed input data */ + shll $8, rc_range(%ebp) + shll $8, rc_code(%ebp) + ADDR32 lodsb + movb %al, (rc_code+0)(%ebp) +1: /* Return current range */ + movl rc_range(%ebp), %eax + ret + .size rc_normalise, . - rc_normalise + +/***************************************************************************** + * Decode single range-encoded bit using a probability estimate + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * %ebx : probability estimate pointer (offset from %ebp) + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * CF : decoded bit + * ZF : inverse of decoded bit + * Corrupts: + * none + ***************************************************************************** + */ +rc_bit: + /* Preserve registers */ + pushl %eax + pushl %edx + /* Perform normalisation */ + call rc_normalise + /* Calculate bound in %eax and probability estimate in %dx */ + shrl $11, %eax + movzwl (%ebp,%ebx), %edx + mul %edx /* will zero %edx */ + movw (%ebp,%ebx), %dx + /* Compare code against bound */ + cmpl %eax, rc_code(%ebp) + jae 2f +1: /* Code is less than bound */ + movl %eax, rc_range(%ebp) + negw %dx + addw $(1<<11), %dx + shrw $5, %dx + addw %dx, (%ebp,%ebx) + xorw %ax, %ax /* Clear CF, set ZF */ + jmp 99f +2: /* Code is greater than or equal to bound */ + subl %eax, rc_range(%ebp) + subl %eax, rc_code(%ebp) + shrw $5, %dx + subw %dx, (%ebp,%ebx) + incw %dx /* Clear ZF (%dx is 11-bit; can never wrap) */ + stc /* Set CF */ +99: /* Restore registers and return */ + popl %edx + popl %eax + ret + .size rc_bit, . - rc_bit + +/***************************************************************************** + * Decode MSB-first bittree + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * %ebx : probability estimate set pointer (offset from %ebp) + * %cx : number of bits to decode + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * %eax : decoded bittree + * Corrupts: + * none + ***************************************************************************** + */ +rc_bittree: + /* Preserve registers */ + pushl %edi + pushw %cx + movl %ebx, %edi + /* Initialise registers */ + movl $1, %eax +1: /* Decode bit */ + leaw (%edi,%eax,2), %bx /* high word always zero anyway */ + call rc_bit + rclw %ax + ADDR16 loop 1b + /* Restore registers, clear unwanted high bit of result, and return */ + movl %edi, %ebx + popw %cx + popl %edi + btrw %cx, %ax + ret + .size rc_bittree, . - rc_bittree + +/***************************************************************************** + * Decode LSB-first bittree + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * %ebx : probability estimate set pointer (offset from %ebp) + * %cx : number of bits to decode + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * %eax : decoded bittree + * Corrupts: + * none + ***************************************************************************** + */ +rc_bittree_reverse: + /* Preserve registers */ + pushw %cx + /* Decode bittree */ + call rc_bittree +1: /* Reverse result */ + rcrb %al + rclb %ah + ADDR16 loop 1b + shrw $8, %ax + /* Restore registers and return */ + popw %cx + ret + .size rc_bittree_reverse, . - rc_bittree_reverse + +/***************************************************************************** + * Decode MSB-first bittree with optional match byte + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * %ebx : probability estimate set pointer (offset from %ebp) + * %cl : match byte + * %ch : 1 to use match byte, 0 to ignore match byte + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * %eax : decoded bittree + * Corrupts: + * none + ***************************************************************************** + */ +rc_bittree_match: + /* Preserve registers */ + pushl %edi + pushw %cx + pushw %dx + movl %ebx, %edi + /* Initialise registers */ + movl $1, %eax +1: /* Decode bit */ + rolb $1, %cl + movw %cx, %dx + andb %dh, %dl /* match_bit in %dl */ + movw %dx, %bx + addb %bl, %bh + xorb %bl, %bl + addw %ax, %bx /* offset + match_bit + symbol */ + leaw (%edi,%ebx,2), %bx /* high word always zero anyway */ + call rc_bit + rclw %ax + movb %al, %dh + notb %dh + xorb %dh, %dl + andb %dl, %ch /* offset &= ( match_bit ^ bit ) */ + testb %ah, %ah + jz 1b + /* Restore registers, clear unwanted high bit of result, and return */ + movl %edi, %ebx + popw %dx + popw %cx + popl %edi + xorb %ah, %ah + ret + .size rc_bittree_match, . - rc_bittree_match + +/***************************************************************************** + * Decode direct bits (no probability estimates) + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * %cx : number of bits to decode + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * %eax : decoded bits + * Corrupts: + * none + ***************************************************************************** + */ +rc_direct: + /* Preserve registers */ + pushl %ebx + pushw %cx + pushl %edx + /* Initialise registers */ + xorl %edx, %edx +1: /* Perform normalisation */ + call rc_normalise + /* Decode bit */ + shrl $1, %eax + movl %eax, rc_range(%ebp) + movl rc_code(%ebp), %ebx + subl %eax, %ebx + js 2f + movl %ebx, rc_code(%ebp) +2: rcll %ebx + rcll %edx + xorb $1, %dl + ADDR16 loop 1b + /* Restore registers and return */ + movl %edx, %eax + popl %edx + popw %cx + popl %ebx + ret + .size rc_direct, . - rc_direct + +/***************************************************************************** + * Decode an LZMA literal + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * %es:%edi : uncompressed output data pointer + * %edx : LZMA state + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * %es:%edi : uncompressed output data pointer (updated) + * %edx : LZMA state + * CF : end of payload marker found (always zero) + * Corrupts: + * %eax + * %ebx + * %ecx + ***************************************************************************** + * + * Literals are coded as an eight-bit tree, using a match byte if the + * previous symbol was not a literal. + * + */ +lzma_literal: + /* Get most recent output byte, if available */ + xorl %ebx, %ebx + cmpl %edi, out_start(%ebp) + je 1f + movb %es:-1(%edi), %bh +1: /* Locate probability estimate set */ + shrb $( 8 - LZMA_LC ), %bh + shlb $1, %bh + leaw literal(%ebx,%ebx,2), %bx + /* Get match byte, if applicable */ + xorw %cx, %cx + cmpb $STATE_LIT_MAX, %dl + jbe 1f + movl rep0(%ebp), %eax + notl %eax + movb %es:(%edi,%eax), %cl + movb $1, %ch +1: /* Decode bittree */ + call rc_bittree_match + /* Store output byte */ + ADDR32 stosb + print_hex_byte %al + print_character $(' ') + /* Update LZMA state */ + subb $3, %dl + jns 1f + xorb %dl, %dl +1: cmpb $7, %dl + jb 1f + subb $3, %dl +1: /* Clear CF and return */ + clc + ret + .size lzma_literal, . - lzma_literal + +/***************************************************************************** + * Decode an LZMA length + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * %ebx : length parameter pointer (offset from %ebp) + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * Corrupts: + * %ebx + ***************************************************************************** + * + * Lengths are encoded as: + * + * "0" + 3 bits : lengths 2-9 ("low") + * "10" + 3 bits : lengths 10-17 ("mid") + * "11" + 8 bits : lengths 18-273 ("high") + */ +lzma_len: + /* Preserve registers */ + pushl %eax + pushl %ecx + pushl %edi + movl %ebx, %edi + /* Start by assuming three bits and a base length of 2 */ + movw $3, %cx + movw $2, len(%ebp) + /* Check low-length choice bit */ + leal choice(%edi), %ebx + call rc_bit + leal low(%edi), %ebx + jz 1f + /* Check high-length choice bit */ + leal choice2(%edi), %ebx + call rc_bit + leal mid(%edi), %ebx + movb $10, len(%ebp) + jz 1f + leal high(%edi), %ebx + movb $8, %cl + movb $18, len(%ebp) +1: /* Get encoded length */ + call rc_bittree + addw %ax, len(%ebp) + /* Restore registers and return */ + movl %edi, %ebx + popl %edi + popl %ecx + popl %eax + ret + .size lzma_len, . - lzma_len + +/***************************************************************************** + * Copy (possibly repeated) matched data + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * %es:%edi : uncompressed output data pointer + * %cl : repeated match distance index (for repeated matches) + * %eax : match distance (for non-repeated matches) + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * %es:%edi : uncompressed output data pointer + * CF : match distance is out of range + * Corrupts: + * %eax + * %ebx + * %ecx + ***************************************************************************** + */ +match: /* Update repeated match list */ + print_character $('[') + movl $3, %ecx + jmp 1f +match_rep: + print_character $('[') + print_character $('R') + print_hex_byte %cl + print_character $('=') + movzbl %cl, %ecx + movl reps(%ebp,%ecx,4), %eax + jcxz 2f +1: movl (reps-4)(%ebp,%ecx,4), %ebx + movl %ebx, reps(%ebp,%ecx,4) + loop 1b + movl %eax, rep0(%ebp) +2: /* Preserve registers */ + pushl %esi + /* Get stored match length */ + movzwl len(%ebp), %ecx + print_hex_dword %eax + print_character $('+') + print_hex_word %cx + print_character $(']') + print_character $(' ') + /* Abort with CF set if match distance is out of range */ + movl out_start(%ebp), %esi + negl %esi + leal -1(%edi,%esi), %esi + cmpl %eax, %esi + jc 99f + /* Perform copy */ + notl %eax + leal (%edi,%eax), %esi + ADDR32 es rep movsb +99: /* Restore registers and return */ + popl %esi + ret + .size match, . - match + +/***************************************************************************** + * Decode an LZMA match + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * %es:%edi : uncompressed output data pointer + * %edx : LZMA state + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * %es:%edi : uncompressed output data pointer + * %edx : LZMA state + * CF : end of payload marker found + * Corrupts: + * %eax + * %ebx + * %ecx + ***************************************************************************** + * + * Matches are encoded as an LZMA length followed by a 6-bit "distance + * slot" code, 0-26 fixed-probability bits, and 0-5 context encoded + * bits. + */ +lzma_match: + /* Preserve registers */ + pushl %edi + /* Update LZMA state */ + cmpb $STATE_LIT_MAX, %dl + movb $STATE_LIT_MATCH, %dl + jbe 1f + movb $STATE_NONLIT_MATCH, %dl +1: /* Decode length */ + movl $match_len_dec, %ebx + call lzma_len + /* Decode distance slot */ + movw len(%ebp), %bx + subw $2, %bx + cmpw $4, %bx + jb 1f + movw $3, %bx +1: shlw $7, %bx + addw $dist_slot, %bx + movw $6, %cx + call rc_bittree + /* Distance slots 0-3 are literal distances */ + cmpb $4, %al + jb 99f + /* Determine initial bits: 10/11 for even/odd distance codes */ + movl %eax, %edi + andw $1, %di + orw $2, %di + /* Determine number of context-encoded bits */ + movw %ax, %cx + shrb $1, %cl + decb %cl + /* Select context to be used in absence of fixed-probability bits */ + movl %edi, %ebx + shlw %cl, %bx + subw %ax, %bx + leaw (dist_special-2)(%ebx,%ebx), %bx + /* Decode fixed-probability bits, if any */ + cmpb $6, %cl + jb 1f + subb $4, %cl + shll %cl, %edi + call rc_direct + orl %eax, %edi + /* Select context to be used in presence of fixed-probability bits */ + movb $4, %cl + movl $dist_align, %ebx +1: /* Decode context-encoded bits */ + shll %cl, %edi + call rc_bittree_reverse + orl %edi, %eax +99: /* Restore registers and tail-call */ + popl %edi + jmp match + .size lzma_match, . - lzma_match + +/***************************************************************************** + * Decode an LZMA repeated match + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * %es:%edi : uncompressed output data pointer + * %edx : LZMA state + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * %es:%edi : uncompressed output data pointer + * %edx : LZMA state + * CF : end of payload marker found + * Corrupts: + * %eax + * %ebx + * %ecx + ***************************************************************************** + * + * Repeated matches are encoded as: + * + * "00" : shortrep0 (implicit length 1) + * "01" + len : longrep0 + * "10" + len : longrep1 + * "110" + len : longrep2 + * "111" + len : longrep3 + */ +lzma_rep_match: + /* Initially assume longrep0 */ + movw $(STATE_LIT_LONGREP << 8), %cx + /* Get is_rep0 bit */ + leal is_rep0(,%edx,2), %ebx + call rc_bit + jnz 1f + /* Get is_rep0_long bit */ + leal is_rep0_long(,%edx,2), %ebx + call rc_bit + jnz 98f + movw $1, len(%ebp) + movb $STATE_LIT_SHORTREP, %ch + jmp 99f +1: /* Get is_rep1 bit */ + incb %cl + leal is_rep1(,%edx,2), %ebx + call rc_bit + jz 98f + /* Get is_rep2 bit */ + incb %cl + leal is_rep2(,%edx,2), %ebx + call rc_bit + adcb $0, %cl +98: /* Decode length */ + movl $rep_len_dec, %ebx + call lzma_len +99: /* Update LZMA state */ + cmpb $STATE_LIT_MAX, %dl + movb %ch, %dl + jbe 1f + movb $STATE_NONLIT_REP, %dl +1: /* Tail call */ + jmp match_rep + .size lzma_match, . - lzma_match + +/***************************************************************************** + * Decode one LZMA symbol + * + * Parameters: + * %ss:%ebp : LZMA parameter block + * %ds:%esi : compressed input data pointer + * %es:%edi : uncompressed output data pointer + * %edx : LZMA state + * Returns: + * %ds:%esi : compressed input data pointer (possibly updated) + * %es:%edi : uncompressed output data pointer (updated) + * %edx : LZMA state + * CF : end of payload marker found + * Corrupts: + * %eax + * %ebx + * %ecx + ***************************************************************************** + */ +lzma_decode: + /* Get is_match bit */ + leal is_match(,%edx,2), %ebx + call rc_bit + jz lzma_literal + /* Get is_rep bit */ + leal is_rep(,%edx,2), %ebx + call rc_bit + jz lzma_match + jmp lzma_rep_match + .size lzma_decode, . - lzma_decode + +/**************************************************************************** + * Undo effect of branch-call-jump (BCJ) filter + * + * Parameters: + * %es:%esi : start of uncompressed output data (note %es) + * %es:%edi : end of uncompressed output data + * Returns: + * Corrupts: + * %eax + * %ebx + * %ecx + * %edx + * %esi + ***************************************************************************** + */ +bcj_filter: + /* Store (negative) start of data in %edx */ + movl %esi, %edx + negl %edx + /* Calculate limit in %ecx */ + leal -5(%edi,%edx), %ecx +1: /* Calculate offset in %ebx */ + leal (%esi,%edx), %ebx + /* Check for end of data */ + cmpl %ecx, %ebx + ja 99f + /* Check for an opcode which would be followed by a rel32 address */ + ADDR32 es lodsb + andb $0xfe, %al + cmpb $0xe8, %al + jne 1b + /* Get current jump target value in %eax */ + ADDR32 es lodsl + /* Convert absolute addresses in the range [0,limit) back to + * relative addresses in the range [-offset,limit-offset). + */ + cmpl %ecx, %eax + jae 2f + subl %ebx,%es:-4(%esi) +2: /* Convert negative numbers in the range [-offset,0) back to + * positive numbers in the range [limit-offset,limit). + */ + notl %eax /* Range is now [0,offset) */ + cmpl %ebx, %eax + jae 1b + addl %ecx,%es:-4(%esi) + jmp 1b +99: /* Return */ + ret + .size bcj_filter, . - bcj_filter + +/**************************************************************************** + * decompress (real-mode or 16/32-bit protected-mode near call) + * + * Decompress data + * + * 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 16-bit registers + * where possible. + **************************************************************************** + */ + .globl decompress +decompress: + /* Preserve registers */ + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + pushl %ebp + /* Allocate parameter block */ + subl $sizeof__lzma_dec, %esp + movl %esp, %ebp + /* Zero parameter block and set all probabilities to 0.5 */ + pushl %edi + pushw %es + pushw %ss + popw %es + movl %ebp, %edi + xorl %eax, %eax + movl $( sizeof__lzma_dec / 4 ), %ecx + ADDR32 rep stosl + leal probs(%ebp), %edi + movw $( ( 1 << 11 ) / 2 ), %ax + movl $( ( sizeof__lzma_dec - probs ) / 2 ), %ecx + ADDR32 rep stosw + popw %es + popl %edi + /* Initialise remaining parameters */ + movl %edi, out_start(%ebp) + print_character $('\n') + ADDR32 lodsb /* discard initial byte */ + print_hex_byte %al + ADDR32 lodsl + bswapl %eax + print_hex_dword %eax + print_character $('\n') + movl %eax, rc_code(%ebp) + decl rc_range(%ebp) + movl $STATE_LIT_LIT, %edx +1: /* Decompress until we reach end of buffer */ + call lzma_decode + jnc 1b + call rc_normalise + print_character $('\n') + /* Undo BCJ filter */ + pushl %esi + movl out_start(%ebp), %esi + call bcj_filter + popl %esi + /* Restore registers and return */ + addl $sizeof__lzma_dec, %esp + popl %ebp + popl %edx + popl %ecx + popl %ebx + popl %eax + ret + + /* Specify minimum amount of stack space required */ + .globl _min_decompress_stack + .equ _min_decompress_stack, ( sizeof__lzma_dec + 512 /* margin */ ) diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/unnrv2b16.S b/qemu/roms/ipxe/src/arch/i386/prefix/unlzma16.S index b24c2846f..32b43f0dc 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/unnrv2b16.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/unlzma16.S @@ -3,7 +3,7 @@ * */ -FILE_LICENCE ( GPL2_OR_LATER ) +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) #define CODE16 -#include "unnrv2b.S" +#include "unlzma.S" diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/unnrv2b.S b/qemu/roms/ipxe/src/arch/i386/prefix/unnrv2b.S deleted file mode 100644 index f5724c134..000000000 --- a/qemu/roms/ipxe/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/qemu/roms/ipxe/src/arch/i386/prefix/usbdisk.S b/qemu/roms/ipxe/src/arch/i386/prefix/usbdisk.S index fa7d1956e..9676406e2 100644 --- a/qemu/roms/ipxe/src/arch/i386/prefix/usbdisk.S +++ b/qemu/roms/ipxe/src/arch/i386/prefix/usbdisk.S @@ -1,3 +1,5 @@ +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) + .text .arch i386 .section ".prefix", "awx", @progbits @@ -6,18 +8,27 @@ #include "mbr.S" -/* Partition table: ZIP-compatible partition 4, 64 heads, 32 sectors/track */ +/* Partition table: 64 heads, 32 sectors/track (ZIP-drive compatible) */ .org 446 .space 16 .space 16 - .space 16 - .byte 0x80, 0x01, 0x01, 0x00 - .byte 0xeb, 0x3f, 0x20, 0x01 + /* Partition 3: log partition (for CONSOLE_INT13) */ + .byte 0x00, 0x01, 0x01, 0x00 + .byte 0xe0, 0x3f, 0x20, 0x00 .long 0x00000020 - .long 0x00000fe0 + .long 0x000007e0 + /* Partition 4: boot partition */ + .byte 0x80, 0x00, 0x01, 0x01 + .byte 0xeb, 0x3f, 0x20, 0x02 + .long 0x00000800 + .long 0x00001000 .org 510 .byte 0x55, 0xaa -/* Skip to start of partition */ +/* Skip to start of log partition */ .org 32 * 512 + .ascii "iPXE LOG\n\n" + +/* Skip to start of boot partition */ + .org 2048 * 512 |