summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/arch/i386/prefix
diff options
context:
space:
mode:
authorJosé Pekkarinen <jose.pekkarinen@nokia.com>2016-05-18 13:18:31 +0300
committerJosé Pekkarinen <jose.pekkarinen@nokia.com>2016-05-18 13:42:15 +0300
commit437fd90c0250dee670290f9b714253671a990160 (patch)
treeb871786c360704244a07411c69fb58da9ead4a06 /qemu/roms/ipxe/src/arch/i386/prefix
parent5bbd6fe9b8bab2a93e548c5a53b032d1939eec05 (diff)
These changes are the raw update to qemu-2.6.
Collission happened in the following patches: migration: do cleanup operation after completion(738df5b9) Bug fix.(1750c932f86) kvmclock: add a new function to update env->tsc.(b52baab2) The code provided by the patches was already in the upstreamed version. Change-Id: I3cc11841a6a76ae20887b2e245710199e1ea7f9a Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'qemu/roms/ipxe/src/arch/i386/prefix')
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/bootpart.S2
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/exeprefix.S6
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/hdprefix.S2
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/isaromprefix.S6
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S6
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S5
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/kpxeprefix.S2
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S75
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/lkrnprefix.S2
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/mbr.S2
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/mromprefix.S7
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/nbiprefix.S2
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/nullprefix.S2
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/pciromprefix.S6
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/pxeprefix.S2
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/romprefix.S31
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/undiloader.S2
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/unlzma.S942
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/unlzma16.S (renamed from qemu/roms/ipxe/src/arch/i386/prefix/unnrv2b16.S)4
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/unnrv2b.S184
-rw-r--r--qemu/roms/ipxe/src/arch/i386/prefix/usbdisk.S23
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