diff options
author | 2016-06-03 03:33:22 +0000 | |
---|---|---|
committer | 2016-06-03 03:33:23 +0000 | |
commit | da27230f80795d0028333713f036d44c53cb0e68 (patch) | |
tree | b3d379eaf000adf72b36cb01cdf4d79c3e3f064c /qemu/roms/ipxe/src/arch/i386/interface/pcbios | |
parent | 0e68cb048bb8aadb14675f5d4286d8ab2fc35449 (diff) | |
parent | 437fd90c0250dee670290f9b714253671a990160 (diff) |
Merge "These changes are the raw update to qemu-2.6."
Diffstat (limited to 'qemu/roms/ipxe/src/arch/i386/interface/pcbios')
13 files changed, 341 insertions, 13 deletions
diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/apm.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/apm.c index 3b13e1cd0..50b19cb81 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/apm.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/apm.c @@ -15,9 +15,13 @@ * 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 ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** * @file diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_nap.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_nap.c index 1e7de756b..f1ba8297b 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_nap.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_nap.c @@ -1,7 +1,7 @@ #include <ipxe/nap.h> #include <realmode.h> -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** * Save power by halting the CPU until the next interrupt diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_reboot.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_reboot.c index 68546b2e5..10a1ecb89 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_reboot.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_reboot.c @@ -15,9 +15,13 @@ * 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 ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** @file * diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_smbios.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_smbios.c index dd7897e29..a8c0fc325 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_smbios.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_smbios.c @@ -15,9 +15,13 @@ * 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 ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <string.h> diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_timer.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_timer.c index 65bbf9e01..3299c9aae 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_timer.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_timer.c @@ -15,9 +15,13 @@ * 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 ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** @file * diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/biosint.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/biosint.c index a193defa3..3b8e80438 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/biosint.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/biosint.c @@ -7,7 +7,7 @@ * */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** * Hook INT vector diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13.c index 1c7a8128f..f0450da90 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13.c @@ -15,9 +15,13 @@ * 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 ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <stdlib.h> diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13con.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13con.c new file mode 100644 index 000000000..2414c6909 --- /dev/null +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13con.c @@ -0,0 +1,284 @@ +/* + * 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 ); + +#include <stdint.h> +#include <string.h> +#include <errno.h> +#include <ipxe/console.h> +#include <ipxe/init.h> +#include <realmode.h> +#include <int13.h> +#include <config/console.h> + +/** @file + * + * INT13 disk log console + * + */ + +/* Set default console usage if applicable */ +#if ! ( defined ( CONSOLE_INT13 ) && CONSOLE_EXPLICIT ( CONSOLE_INT13 ) ) +#undef CONSOLE_INT13 +#define CONSOLE_INT13 ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG ) +#endif + +/** Disk drive number */ +#define INT13CON_DRIVE 0x80 + +/** Log partition type */ +#define INT13CON_PARTITION_TYPE 0xe0 + +/** Maximum number of outstanding unwritten characters */ +#define INT13CON_MAX_UNWRITTEN 64 + +/** Log partition header */ +struct int13con_header { + /** Magic signature */ + char magic[10]; +} __attribute__ (( packed )); + +/** Log partition magic signature */ +#define INT13CON_MAGIC "iPXE LOG\n\n" + +/** Sector buffer */ +static uint8_t __bss16_array ( int13con_buffer, [INT13_BLKSIZE] ); +#define int13con_buffer __use_data16 ( int13con_buffer ) + +/** Disk address packet */ +static struct int13_disk_address __bss16 ( int13con_address ); +#define int13con_address __use_data16 ( int13con_address ) + +/** Current LBA */ +static uint64_t int13con_lba; + +/** Maximum LBA */ +static uint64_t int13con_max_lba; + +/** Current offset within sector */ +static size_t int13con_offset; + +/** Number of unwritten characters */ +static size_t int13con_unwritten; + +struct console_driver int13con __console_driver; + +/** + * Read/write disk sector + * + * @v op Operation + * @v lba Logical block address + * @ret rc Return status code + */ +static int int13con_rw ( unsigned int op, uint64_t lba ) { + uint8_t error; + + /* Construct disk address packet */ + int13con_address.bufsize = sizeof ( int13con_address ); + int13con_address.count = 1; + int13con_address.buffer.segment = rm_ds; + int13con_address.buffer.offset = __from_data16 ( int13con_buffer ); + int13con_address.lba = lba; + + /* Issue INT13 */ + __asm__ ( REAL_CODE ( "int $0x13\n\t" ) + : "=a" ( error ) + : "0" ( op << 8 ), "d" ( INT13CON_DRIVE ), + "S" ( __from_data16 ( &int13con_address ) ) ); + if ( error ) { + DBG ( "INT13CON operation %04x failed: %02x\n", + op, error ); + return -EIO; + } + + return 0; +} + +/** + * Write character to console + * + * @v character Character + */ +static void int13con_putchar ( int character ) { + static int busy; + int rc; + + /* Ignore if we are already mid-logging */ + if ( busy ) + return; + busy = 1; + + /* Write character to buffer */ + int13con_buffer[int13con_offset++] = character; + int13con_unwritten++; + + /* Write sector to disk, if applicable */ + if ( ( int13con_offset == INT13_BLKSIZE ) || + ( int13con_unwritten == INT13CON_MAX_UNWRITTEN ) || + ( character == '\n' ) ) { + + /* Write sector to disk */ + if ( ( rc = int13con_rw ( INT13_EXTENDED_WRITE, + int13con_lba ) ) != 0 ) { + DBG ( "INT13CON could not write log\n" ); + /* Ignore and continue; there's nothing we can do */ + } + + /* Reset count of unwritten characters */ + int13con_unwritten = 0; + } + + /* Move to next sector, if applicable */ + if ( int13con_offset == INT13_BLKSIZE ) { + + /* Disable console if we have run out of space */ + if ( int13con_lba >= int13con_max_lba ) + int13con.disabled = 1; + + /* Clear log buffer */ + memset ( int13con_buffer, 0, sizeof ( int13con_buffer ) ); + int13con_offset = 0; + + /* Move to next sector */ + int13con_lba++; + } + + /* Clear busy flag */ + busy = 0; +} + +/** + * Find log partition + * + * @ret rc Return status code + */ +static int int13con_find ( void ) { + struct master_boot_record *mbr = + ( ( struct master_boot_record * ) int13con_buffer ); + struct int13con_header *hdr = + ( ( struct int13con_header * ) int13con_buffer ); + struct partition_table_entry part[4]; + unsigned int i; + int rc; + + /* Read MBR */ + if ( ( rc = int13con_rw ( INT13_EXTENDED_READ, 0 ) ) != 0 ) { + DBG ( "INT13CON could not read MBR: %s\n", strerror ( rc ) ); + return rc; + } + + /* Check MBR magic */ + if ( mbr->magic != INT13_MBR_MAGIC ) { + DBG ( "INT13CON incorrect MBR magic\n" ); + DBG2_HDA ( 0, mbr, sizeof ( *mbr ) ); + return -EINVAL; + } + + /* Look for magic partition */ + memcpy ( part, mbr->partitions, sizeof ( part ) ); + for ( i = 0 ; i < ( sizeof ( part ) / sizeof ( part[0] ) ) ; i++ ) { + + /* Skip partitions of the wrong type */ + if ( part[i].type != INT13CON_PARTITION_TYPE ) + continue; + + /* Read partition header */ + if ( ( rc = int13con_rw ( INT13_EXTENDED_READ, + part[i].start ) ) != 0 ) { + DBG ( "INT13CON partition %d could not read header: " + "%s\n", ( i + 1 ), strerror ( rc ) ); + continue; + } + + /* Check partition header */ + if ( memcmp ( hdr->magic, INT13CON_MAGIC, + sizeof ( hdr->magic ) ) != 0 ) { + DBG ( "INT13CON partition %d bad magic\n", ( i + 1 ) ); + DBG2_HDA ( 0, hdr, sizeof ( *hdr ) ); + continue; + } + + /* Found log partition */ + DBG ( "INT13CON partition %d at [%08x,%08x)\n", ( i + 1 ), + part[i].start, ( part[i].start + part[i].length ) ); + int13con_lba = part[i].start; + int13con_max_lba = ( part[i].start + part[i].length - 1 ); + + /* Initialise log buffer */ + memset ( &int13con_buffer[ sizeof ( *hdr ) ], 0, + ( sizeof ( int13con_buffer ) - sizeof ( *hdr ) ) ); + int13con_offset = sizeof ( hdr->magic ); + + return 0; + } + + DBG ( "INT13CON found no log partition\n" ); + return -ENOENT; +} + +/** + * Initialise INT13 console + * + */ +static void int13con_init ( void ) { + uint8_t error; + uint16_t check; + unsigned int discard_c; + unsigned int discard_d; + int rc; + + /* Check for INT13 extensions */ + __asm__ __volatile__ ( REAL_CODE ( "int $0x13\n\t" + "setc %%al\n\t" ) + : "=a" ( error ), "=b" ( check ), + "=c" ( discard_c ), "=d" ( discard_d ) + : "0" ( INT13_EXTENSION_CHECK << 8 ), + "1" ( 0x55aa ), "3" ( INT13CON_DRIVE ) ); + if ( error || ( check != 0xaa55 ) ) { + DBG ( "INT13CON missing extensions (%02x,%04x)\n", + error, check ); + return; + } + + /* Locate log partition */ + if ( ( rc = int13con_find() ) != 0) + return; + + /* Enable console */ + int13con.disabled = 0; +} + +/** + * INT13 console initialisation function + */ +struct init_fn int13con_init_fn __init_fn ( INIT_CONSOLE ) = { + .initialise = int13con_init, +}; + +/** INT13 console driver */ +struct console_driver int13con __console_driver = { + .putchar = int13con_putchar, + .disabled = CONSOLE_DISABLED, + .usage = CONSOLE_INT13, +}; diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/memtop_umalloc.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/memtop_umalloc.c index c382e3c36..957f8e324 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/memtop_umalloc.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/memtop_umalloc.c @@ -15,9 +15,13 @@ * 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 ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** * @file diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/pcibios.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/pcibios.c index 61873039f..34efa0b39 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/pcibios.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/pcibios.c @@ -15,9 +15,13 @@ * 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 ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <ipxe/pci.h> @@ -38,7 +42,11 @@ static int pcibios_num_bus ( void ) { int discard_a, discard_D; uint8_t max_bus; - __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" + /* We issue this call using flat real mode, to work around a + * bug in some HP BIOSes. + */ + __asm__ __volatile__ ( REAL_CODE ( "call flatten_real_mode\n\t" + "stc\n\t" "int $0x1a\n\t" "jnc 1f\n\t" "xorw %%cx, %%cx\n\t" diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_entropy.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_entropy.c index fad421c2a..9aab03c03 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_entropy.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_entropy.c @@ -15,9 +15,13 @@ * 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 ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** @file * diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_time.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_time.c index 67041d4ca..cdbeac8d5 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_time.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_time.c @@ -15,9 +15,13 @@ * 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 ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** @file * diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/vesafb.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/vesafb.c index 2adc7b040..9cf2bf29e 100644 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/vesafb.c +++ b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/vesafb.c @@ -15,9 +15,13 @@ * 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 ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** @file * |