diff options
author | 2017-04-25 03:31:15 -0700 | |
---|---|---|
committer | 2017-05-22 06:48:08 +0000 | |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/ipxe/src/arch/i386/firmware/pcbios | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/ipxe/src/arch/i386/firmware/pcbios')
7 files changed, 0 insertions, 1825 deletions
diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/basemem.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/basemem.c deleted file mode 100644 index 6a46081aa..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/basemem.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * 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 <realmode.h> -#include <bios.h> -#include <basemem.h> -#include <ipxe/hidemem.h> - -/** @file - * - * Base memory allocation - * - */ - -/** - * Set the BIOS free base memory counter - * - * @v new_fbms New free base memory counter (in kB) - */ -void set_fbms ( unsigned int new_fbms ) { - uint16_t fbms = new_fbms; - - /* Update the BIOS memory counter */ - put_real ( fbms, BDA_SEG, BDA_FBMS ); - - /* Update our hidden memory region map */ - hide_basemem(); -} diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/bios_console.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/bios_console.c deleted file mode 100644 index 63413cdc1..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/bios_console.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * 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 <assert.h> -#include <realmode.h> -#include <bios.h> -#include <ipxe/console.h> -#include <ipxe/ansiesc.h> -#include <ipxe/keymap.h> -#include <config/console.h> - -#define ATTR_BOLD 0x08 - -#define ATTR_FCOL_MASK 0x07 -#define ATTR_FCOL_BLACK 0x00 -#define ATTR_FCOL_BLUE 0x01 -#define ATTR_FCOL_GREEN 0x02 -#define ATTR_FCOL_CYAN 0x03 -#define ATTR_FCOL_RED 0x04 -#define ATTR_FCOL_MAGENTA 0x05 -#define ATTR_FCOL_YELLOW 0x06 -#define ATTR_FCOL_WHITE 0x07 - -#define ATTR_BLINK 0x80 - -#define ATTR_BCOL_MASK 0x70 -#define ATTR_BCOL_BLACK 0x00 -#define ATTR_BCOL_BLUE 0x10 -#define ATTR_BCOL_GREEN 0x20 -#define ATTR_BCOL_CYAN 0x30 -#define ATTR_BCOL_RED 0x40 -#define ATTR_BCOL_MAGENTA 0x50 -#define ATTR_BCOL_YELLOW 0x60 -#define ATTR_BCOL_WHITE 0x70 - -#define ATTR_DEFAULT ATTR_FCOL_WHITE - -/* Set default console usage if applicable */ -#if ! ( defined ( CONSOLE_PCBIOS ) && CONSOLE_EXPLICIT ( CONSOLE_PCBIOS ) ) -#undef CONSOLE_PCBIOS -#define CONSOLE_PCBIOS ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG ) -#endif - -/** Current character attribute */ -static unsigned int bios_attr = ATTR_DEFAULT; - -/** - * Handle ANSI CUP (cursor position) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params[0] Row (1 is top) - * @v params[1] Column (1 is left) - */ -static void bios_handle_cup ( struct ansiesc_context *ctx __unused, - unsigned int count __unused, int params[] ) { - int cx = ( params[1] - 1 ); - int cy = ( params[0] - 1 ); - - if ( cx < 0 ) - cx = 0; - if ( cy < 0 ) - cy = 0; - - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x10\n\t" - "cli\n\t" ) - : : "a" ( 0x0200 ), "b" ( 1 ), - "d" ( ( cy << 8 ) | cx ) ); -} - -/** - * Handle ANSI ED (erase in page) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params[0] Region to erase - */ -static void bios_handle_ed ( struct ansiesc_context *ctx __unused, - unsigned int count __unused, - int params[] __unused ) { - /* We assume that we always clear the whole screen */ - assert ( params[0] == ANSIESC_ED_ALL ); - - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x10\n\t" - "cli\n\t" ) - : : "a" ( 0x0600 ), "b" ( bios_attr << 8 ), - "c" ( 0 ), - "d" ( ( ( console_height - 1 ) << 8 ) | - ( console_width - 1 ) ) ); -} - -/** - * Handle ANSI SGR (set graphics rendition) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params List of graphic rendition aspects - */ -static void bios_handle_sgr ( struct ansiesc_context *ctx __unused, - unsigned int count, int params[] ) { - static const uint8_t bios_attr_fcols[10] = { - ATTR_FCOL_BLACK, ATTR_FCOL_RED, ATTR_FCOL_GREEN, - ATTR_FCOL_YELLOW, ATTR_FCOL_BLUE, ATTR_FCOL_MAGENTA, - ATTR_FCOL_CYAN, ATTR_FCOL_WHITE, - ATTR_FCOL_WHITE, ATTR_FCOL_WHITE /* defaults */ - }; - static const uint8_t bios_attr_bcols[10] = { - ATTR_BCOL_BLACK, ATTR_BCOL_RED, ATTR_BCOL_GREEN, - ATTR_BCOL_YELLOW, ATTR_BCOL_BLUE, ATTR_BCOL_MAGENTA, - ATTR_BCOL_CYAN, ATTR_BCOL_WHITE, - ATTR_BCOL_BLACK, ATTR_BCOL_BLACK /* defaults */ - }; - unsigned int i; - int aspect; - - for ( i = 0 ; i < count ; i++ ) { - aspect = params[i]; - if ( aspect == 0 ) { - bios_attr = ATTR_DEFAULT; - } else if ( aspect == 1 ) { - bios_attr |= ATTR_BOLD; - } else if ( aspect == 5 ) { - bios_attr |= ATTR_BLINK; - } else if ( aspect == 22 ) { - bios_attr &= ~ATTR_BOLD; - } else if ( aspect == 25 ) { - bios_attr &= ~ATTR_BLINK; - } else if ( ( aspect >= 30 ) && ( aspect <= 39 ) ) { - bios_attr &= ~ATTR_FCOL_MASK; - bios_attr |= bios_attr_fcols[ aspect - 30 ]; - } else if ( ( aspect >= 40 ) && ( aspect <= 49 ) ) { - bios_attr &= ~ATTR_BCOL_MASK; - bios_attr |= bios_attr_bcols[ aspect - 40 ]; - } - } -} - -/** - * Handle ANSI DECTCEM set (show cursor) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params List of graphic rendition aspects - */ -static void bios_handle_dectcem_set ( struct ansiesc_context *ctx __unused, - unsigned int count __unused, - int params[] __unused ) { - uint8_t height; - - /* Get character height */ - get_real ( height, BDA_SEG, BDA_CHAR_HEIGHT ); - - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x10\n\t" - "cli\n\t" ) - : : "a" ( 0x0100 ), - "c" ( ( ( height - 2 ) << 8 ) | - ( height - 1 ) ) ); -} - -/** - * Handle ANSI DECTCEM reset (hide cursor) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params List of graphic rendition aspects - */ -static void bios_handle_dectcem_reset ( struct ansiesc_context *ctx __unused, - unsigned int count __unused, - int params[] __unused ) { - - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x10\n\t" - "cli\n\t" ) - : : "a" ( 0x0100 ), "c" ( 0x2000 ) ); -} - -/** BIOS console ANSI escape sequence handlers */ -static struct ansiesc_handler bios_ansiesc_handlers[] = { - { ANSIESC_CUP, bios_handle_cup }, - { ANSIESC_ED, bios_handle_ed }, - { ANSIESC_SGR, bios_handle_sgr }, - { ANSIESC_DECTCEM_SET, bios_handle_dectcem_set }, - { ANSIESC_DECTCEM_RESET, bios_handle_dectcem_reset }, - { 0, NULL } -}; - -/** BIOS console ANSI escape sequence context */ -static struct ansiesc_context bios_ansiesc_ctx = { - .handlers = bios_ansiesc_handlers, -}; - -/** - * Print a character to BIOS console - * - * @v character Character to be printed - */ -static void bios_putchar ( int character ) { - int discard_a, discard_b, discard_c; - - /* Intercept ANSI escape sequences */ - character = ansiesc_process ( &bios_ansiesc_ctx, character ); - if ( character < 0 ) - return; - - /* Print character with attribute */ - __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */ - "sti\n\t" - /* Skip non-printable characters */ - "cmpb $0x20, %%al\n\t" - "jb 1f\n\t" - /* Read attribute */ - "movb %%al, %%cl\n\t" - "movb $0x08, %%ah\n\t" - "int $0x10\n\t" - "xchgb %%al, %%cl\n\t" - /* Skip if attribute matches */ - "cmpb %%ah, %%bl\n\t" - "je 1f\n\t" - /* Set attribute */ - "movw $0x0001, %%cx\n\t" - "movb $0x09, %%ah\n\t" - "int $0x10\n\t" - "\n1:\n\t" - /* Print character */ - "xorw %%bx, %%bx\n\t" - "movb $0x0e, %%ah\n\t" - "int $0x10\n\t" - "cli\n\t" - "popl %%ebp\n\t" /* gcc bug */ ) - : "=a" ( discard_a ), "=b" ( discard_b ), - "=c" ( discard_c ) - : "a" ( character ), "b" ( bios_attr ) ); -} - -/** - * Pointer to current ANSI output sequence - * - * While we are in the middle of returning an ANSI sequence for a - * special key, this will point to the next character to return. When - * not in the middle of such a sequence, this will point to a NUL - * (note: not "will be NULL"). - */ -static const char *ansi_input = ""; - -/** A mapping from a BIOS scan code to an ANSI escape sequence */ -#define BIOS_KEY( key, ansi ) key ansi "\0" - -/** Mapping from BIOS scan codes to ANSI escape sequences */ -static const char ansi_sequences[] = { - BIOS_KEY ( "\x53", "[3~" ) /* Delete */ - BIOS_KEY ( "\x48", "[A" ) /* Up arrow */ - BIOS_KEY ( "\x50", "[B" ) /* Down arrow */ - BIOS_KEY ( "\x4b", "[D" ) /* Left arrow */ - BIOS_KEY ( "\x4d", "[C" ) /* Right arrow */ - BIOS_KEY ( "\x47", "[H" ) /* Home */ - BIOS_KEY ( "\x4f", "[F" ) /* End */ - BIOS_KEY ( "\x49", "[5~" ) /* Page up */ - BIOS_KEY ( "\x51", "[6~" ) /* Page down */ - BIOS_KEY ( "\x3f", "[15~" ) /* F5 */ - BIOS_KEY ( "\x40", "[17~" ) /* F6 */ - BIOS_KEY ( "\x41", "[18~" ) /* F7 */ - BIOS_KEY ( "\x42", "[19~" ) /* F8 (required for PXE) */ - BIOS_KEY ( "\x43", "[20~" ) /* F9 */ - BIOS_KEY ( "\x44", "[21~" ) /* F10 */ - BIOS_KEY ( "\x85", "[23~" ) /* F11 */ - BIOS_KEY ( "\x86", "[24~" ) /* F12 */ -}; - -/** - * Get ANSI escape sequence corresponding to BIOS scancode - * - * @v scancode BIOS scancode - * @ret ansi_seq ANSI escape sequence, if any, otherwise NULL - */ -static const char * scancode_to_ansi_seq ( unsigned int scancode ) { - const char *seq = ansi_sequences; - - while ( *seq ) { - if ( *(seq++) == ( ( char ) scancode ) ) - return seq; - seq += ( strlen ( seq ) + 1 ); - } - DBG ( "Unrecognised BIOS scancode %02x\n", scancode ); - return NULL; -} - -/** - * Map a key - * - * @v character Character read from console - * @ret character Mapped character - */ -static int bios_keymap ( unsigned int character ) { - struct key_mapping *mapping; - - for_each_table_entry ( mapping, KEYMAP ) { - if ( mapping->from == character ) - return mapping->to; - } - return character; -} - -/** - * Get character from BIOS console - * - * @ret character Character read from console - */ -static int bios_getchar ( void ) { - uint16_t keypress; - unsigned int character; - const char *ansi_seq; - - /* If we are mid-sequence, pass out the next byte */ - if ( ( character = *ansi_input ) ) { - ansi_input++; - return character; - } - - /* Read character from real BIOS console */ - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x16\n\t" - "cli\n\t" ) - : "=a" ( keypress ) : "a" ( 0x1000 ) ); - character = ( keypress & 0xff ); - - /* If it's a normal character, just map and return it */ - if ( character && ( character < 0x80 ) ) - return bios_keymap ( character ); - - /* Otherwise, check for a special key that we know about */ - if ( ( ansi_seq = scancode_to_ansi_seq ( keypress >> 8 ) ) ) { - /* Start of escape sequence: return ESC (0x1b) */ - ansi_input = ansi_seq; - return 0x1b; - } - - return 0; -} - -/** - * Check for character ready to read from BIOS console - * - * @ret True Character available to read - * @ret False No character available to read - */ -static int bios_iskey ( void ) { - unsigned int discard_a; - unsigned int flags; - - /* If we are mid-sequence, we are always ready */ - if ( *ansi_input ) - return 1; - - /* Otherwise check the real BIOS console */ - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x16\n\t" - "pushfw\n\t" - "popw %w0\n\t" - "cli\n\t" ) - : "=r" ( flags ), "=a" ( discard_a ) - : "a" ( 0x1100 ) ); - return ( ! ( flags & ZF ) ); -} - -struct console_driver bios_console __console_driver = { - .putchar = bios_putchar, - .getchar = bios_getchar, - .iskey = bios_iskey, - .usage = CONSOLE_PCBIOS, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/e820mangler.S b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/e820mangler.S deleted file mode 100644 index d5d97b482..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/e820mangler.S +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * 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 ) - - .text - .arch i386 - .code16 - -#define SMAP 0x534d4150 - -/* Most documentation refers to the E820 buffer as being 20 bytes, and - * the API makes it perfectly legitimate to pass only a 20-byte buffer - * and expect to get valid data. However, some morons at ACPI decided - * to extend the data structure by adding an extra "extended - * attributes" field and by including critical information within this - * field, such as whether or not the region is enabled. A caller who - * passes in only a 20-byte buffer therefore risks getting very, very - * misleading information. - * - * I have personally witnessed an HP BIOS that returns a value of - * 0x0009 in the extended attributes field. If we don't pass this - * value through to the caller, 32-bit WinPE will die, usually with a - * PAGE_FAULT_IN_NONPAGED_AREA blue screen of death. - * - * Allow a ridiculously large maximum value (64 bytes) for the E820 - * buffer as a guard against insufficiently creative idiots in the - * future. - */ -#define E820MAXSIZE 64 - -/**************************************************************************** - * - * Allowed memory windows - * - * There are two ways to view this list. The first is as a list of - * (non-overlapping) allowed memory regions, sorted by increasing - * address. The second is as a list of (non-overlapping) hidden - * memory regions, again sorted by increasing address. The second - * view is offset by half an entry from the first: think about this - * for a moment and it should make sense. - * - * xxx_memory_window is used to indicate an "allowed region" - * structure, hidden_xxx_memory is used to indicate a "hidden region" - * structure. Each structure is 16 bytes in length. - * - **************************************************************************** - */ - .section ".data16", "aw", @progbits - .align 16 - .globl hidemem_base - .globl hidemem_umalloc - .globl hidemem_textdata -memory_windows: -base_memory_window: .long 0x00000000, 0x00000000 /* Start of memory */ - -hidemem_base: .long 0x000a0000, 0x00000000 /* Changes at runtime */ -ext_memory_window: .long 0x000a0000, 0x00000000 /* 640kB mark */ - -hidemem_umalloc: .long 0xffffffff, 0xffffffff /* Changes at runtime */ - .long 0xffffffff, 0xffffffff /* Changes at runtime */ - -hidemem_textdata: .long 0xffffffff, 0xffffffff /* Changes at runtime */ - .long 0xffffffff, 0xffffffff /* Changes at runtime */ - - .long 0xffffffff, 0xffffffff /* End of memory */ -memory_windows_end: - -/**************************************************************************** - * Truncate region to memory window - * - * Parameters: - * %edx:%eax Start of region - * %ecx:%ebx Length of region - * %si Memory window - * Returns: - * %edx:%eax Start of windowed region - * %ecx:%ebx Length of windowed region - **************************************************************************** - */ - .section ".text16", "ax", @progbits -window_region: - /* Convert (start,len) to (start, end) */ - addl %eax, %ebx - adcl %edx, %ecx - /* Truncate to window start */ - cmpl 4(%si), %edx - jne 1f - cmpl 0(%si), %eax -1: jae 2f - movl 4(%si), %edx - movl 0(%si), %eax -2: /* Truncate to window end */ - cmpl 12(%si), %ecx - jne 1f - cmpl 8(%si), %ebx -1: jbe 2f - movl 12(%si), %ecx - movl 8(%si), %ebx -2: /* Convert (start, end) back to (start, len) */ - subl %eax, %ebx - sbbl %edx, %ecx - /* If length is <0, set length to 0 */ - jae 1f - xorl %ebx, %ebx - xorl %ecx, %ecx - ret - .size window_region, . - window_region - -/**************************************************************************** - * Patch "memory above 1MB" figure - * - * Parameters: - * %ax Memory above 1MB, in 1kB blocks - * Returns: - * %ax Modified memory above 1M in 1kB blocks - **************************************************************************** - */ - .section ".text16", "ax", @progbits -patch_1m: - pushal - /* Convert to (start,len) format and call truncate */ - xorl %ecx, %ecx - movzwl %ax, %ebx - shll $10, %ebx - xorl %edx, %edx - movl $0x100000, %eax - movw $ext_memory_window, %si - call window_region - /* Convert back to "memory above 1MB" format and return via %ax */ - pushfw - shrl $10, %ebx - popfw - movw %sp, %bp - movw %bx, 28(%bp) - popal - ret - .size patch_1m, . - patch_1m - -/**************************************************************************** - * Patch "memory above 16MB" figure - * - * Parameters: - * %bx Memory above 16MB, in 64kB blocks - * Returns: - * %bx Modified memory above 16M in 64kB blocks - **************************************************************************** - */ - .section ".text16", "ax", @progbits -patch_16m: - pushal - /* Convert to (start,len) format and call truncate */ - xorl %ecx, %ecx - shll $16, %ebx - xorl %edx, %edx - movl $0x1000000, %eax - movw $ext_memory_window, %si - call window_region - /* Convert back to "memory above 16MB" format and return via %bx */ - pushfw - shrl $16, %ebx - popfw - movw %sp, %bp - movw %bx, 16(%bp) - popal - ret - .size patch_16m, . - patch_16m - -/**************************************************************************** - * Patch "memory between 1MB and 16MB" and "memory above 16MB" figures - * - * Parameters: - * %ax Memory between 1MB and 16MB, in 1kB blocks - * %bx Memory above 16MB, in 64kB blocks - * Returns: - * %ax Modified memory between 1MB and 16MB, in 1kB blocks - * %bx Modified memory above 16MB, in 64kB blocks - **************************************************************************** - */ - .section ".text16", "ax", @progbits -patch_1m_16m: - call patch_1m - call patch_16m - /* If 1M region is no longer full-length, kill off the 16M region */ - cmpw $( 15 * 1024 ), %ax - je 1f - xorw %bx, %bx -1: ret - .size patch_1m_16m, . - patch_1m_16m - -/**************************************************************************** - * Get underlying e820 memory region to underlying_e820 buffer - * - * Parameters: - * As for INT 15,e820 - * Returns: - * As for INT 15,e820 - * - * Wraps the underlying INT 15,e820 call so that the continuation - * value (%ebx) is a 16-bit simple sequence counter (with the high 16 - * bits ignored), and termination is always via CF=1 rather than - * %ebx=0. - * - **************************************************************************** - */ - .section ".text16", "ax", @progbits -get_underlying_e820: - - /* If the requested region is in the cache, return it */ - cmpw %bx, underlying_e820_index - jne 2f - pushw %di - pushw %si - movw $underlying_e820_cache, %si - cmpl underlying_e820_cache_size, %ecx - jbe 1f - movl underlying_e820_cache_size, %ecx -1: pushl %ecx - rep movsb - popl %ecx - popw %si - popw %di - incw %bx - movl %edx, %eax - clc - ret -2: - /* If the requested region is earlier than the cached region, - * invalidate the cache. - */ - cmpw %bx, underlying_e820_index - jbe 1f - movw $0xffff, underlying_e820_index -1: - /* If the cache is invalid, reset the underlying %ebx */ - cmpw $0xffff, underlying_e820_index - jne 1f - andl $0, underlying_e820_ebx -1: - /* If the cache is valid but the continuation value is zero, - * this means that the previous underlying call returned with - * %ebx=0. Return with CF=1 in this case. - */ - cmpw $0xffff, underlying_e820_index - je 1f - cmpl $0, underlying_e820_ebx - jne 1f - stc - ret -1: - /* Get the next region into the cache */ - pushl %eax - pushl %ebx - pushl %ecx - pushl %edx - pushl %esi /* Some implementations corrupt %esi, so we */ - pushl %edi /* preserve %esi, %edi and %ebp to be paranoid */ - pushl %ebp - pushw %es - pushw %ds - popw %es - movw $underlying_e820_cache, %di - cmpl $E820MAXSIZE, %ecx - jbe 1f - movl $E820MAXSIZE, %ecx -1: movl underlying_e820_ebx, %ebx - stc - pushfw - lcall *%cs:int15_vector - popw %es - popl %ebp - popl %edi - popl %esi - /* Check for error return from underlying e820 call */ - jc 2f /* CF set: error */ - cmpl $SMAP, %eax - je 3f /* 'SMAP' missing: error */ -2: /* An error occurred: return values returned by underlying e820 call */ - stc /* Force CF set if SMAP was missing */ - addr32 leal 16(%esp), %esp /* avoid changing other flags */ - ret -3: /* No error occurred */ - movl %ebx, underlying_e820_ebx - movl %ecx, underlying_e820_cache_size - popl %edx - popl %ecx - popl %ebx - popl %eax - /* Mark cache as containing this result */ - incw underlying_e820_index - - /* Loop until found */ - jmp get_underlying_e820 - .size get_underlying_e820, . - get_underlying_e820 - - .section ".data16", "aw", @progbits -underlying_e820_index: - .word 0xffff /* Initialise to an invalid value */ - .size underlying_e820_index, . - underlying_e820_index - - .section ".bss16", "aw", @nobits -underlying_e820_ebx: - .long 0 - .size underlying_e820_ebx, . - underlying_e820_ebx - - .section ".bss16", "aw", @nobits -underlying_e820_cache: - .space E820MAXSIZE - .size underlying_e820_cache, . - underlying_e820_cache - - .section ".bss16", "aw", @nobits -underlying_e820_cache_size: - .long 0 - .size underlying_e820_cache_size, . - underlying_e820_cache_size - -/**************************************************************************** - * Get windowed e820 region, without empty region stripping - * - * Parameters: - * As for INT 15,e820 - * Returns: - * As for INT 15,e820 - * - * Wraps the underlying INT 15,e820 call so that each underlying - * region is returned N times, windowed to fit within N visible-memory - * windows. Termination is always via CF=1. - * - **************************************************************************** - */ - .section ".text16", "ax", @progbits -get_windowed_e820: - - /* Preserve registers */ - pushl %esi - pushw %bp - - /* Split %ebx into %si:%bx, store original %bx in %bp */ - pushl %ebx - popw %bp - popw %si - - /* %si == 0 => start of memory_windows list */ - testw %si, %si - jne 1f - movw $memory_windows, %si -1: - /* Get (cached) underlying e820 region to buffer */ - call get_underlying_e820 - jc 99f /* Abort on error */ - - /* Preserve registers */ - pushal - /* start => %edx:%eax, len => %ecx:%ebx */ - movl %es:0(%di), %eax - movl %es:4(%di), %edx - movl %es:8(%di), %ebx - movl %es:12(%di), %ecx - /* Truncate region to current window */ - call window_region -1: /* Store modified values in e820 map entry */ - movl %eax, %es:0(%di) - movl %edx, %es:4(%di) - movl %ebx, %es:8(%di) - movl %ecx, %es:12(%di) - /* Restore registers */ - popal - - /* Derive continuation value for next call */ - addw $16, %si - cmpw $memory_windows_end, %si - jne 1f - /* End of memory windows: reset %si and allow %bx to continue */ - xorw %si, %si - jmp 2f -1: /* More memory windows to go: restore original %bx */ - movw %bp, %bx -2: /* Construct %ebx from %si:%bx */ - pushw %si - pushw %bx - popl %ebx - -98: /* Clear CF */ - clc -99: /* Restore registers and return */ - popw %bp - popl %esi - ret - .size get_windowed_e820, . - get_windowed_e820 - -/**************************************************************************** - * Get windowed e820 region, with empty region stripping - * - * Parameters: - * As for INT 15,e820 - * Returns: - * As for INT 15,e820 - * - * Wraps the underlying INT 15,e820 call so that each underlying - * region is returned up to N times, windowed to fit within N - * visible-memory windows. Empty windows are never returned. - * Termination is always via CF=1. - * - **************************************************************************** - */ - .section ".text16", "ax", @progbits -get_nonempty_e820: - - /* Record entry parameters */ - pushl %eax - pushl %ecx - pushl %edx - - /* Get next windowed region */ - call get_windowed_e820 - jc 99f /* abort on error */ - - /* If region is non-empty, finish here */ - cmpl $0, %es:8(%di) - jne 98f - cmpl $0, %es:12(%di) - jne 98f - - /* Region was empty: restore entry parameters and go to next region */ - popl %edx - popl %ecx - popl %eax - jmp get_nonempty_e820 - -98: /* Clear CF */ - clc -99: /* Return values from underlying call */ - addr32 leal 12(%esp), %esp /* avoid changing flags */ - ret - .size get_nonempty_e820, . - get_nonempty_e820 - -/**************************************************************************** - * Get mangled e820 region, with empty region stripping - * - * Parameters: - * As for INT 15,e820 - * Returns: - * As for INT 15,e820 - * - * Wraps the underlying INT 15,e820 call so that underlying regions - * are windowed to the allowed memory regions. Empty regions are - * stripped from the map. Termination is always via %ebx=0. - * - **************************************************************************** - */ - .section ".text16", "ax", @progbits -get_mangled_e820: - - /* Get a nonempty region */ - call get_nonempty_e820 - jc 99f /* Abort on error */ - - /* Peek ahead to see if there are any further nonempty regions */ - pushal - pushw %es - movw %sp, %bp - subw %cx, %sp - movl $0xe820, %eax - movl $SMAP, %edx - pushw %ss - popw %es - movw %sp, %di - call get_nonempty_e820 - movw %bp, %sp - popw %es - popal - jnc 99f /* There are further nonempty regions */ - - /* No futher nonempty regions: zero %ebx and clear CF */ - xorl %ebx, %ebx - -99: /* Return */ - ret - .size get_mangled_e820, . - get_mangled_e820 - -/**************************************************************************** - * INT 15,e820 handler - **************************************************************************** - */ - .section ".text16", "ax", @progbits -int15_e820: - pushw %ds - pushw %cs:rm_ds - popw %ds - call get_mangled_e820 - popw %ds - call patch_cf - iret - .size int15_e820, . - int15_e820 - -/**************************************************************************** - * INT 15,e801 handler - **************************************************************************** - */ - .section ".text16", "ax", @progbits -int15_e801: - /* Call previous handler */ - pushfw - lcall *%cs:int15_vector - call patch_cf - /* Edit result */ - pushw %ds - pushw %cs:rm_ds - popw %ds - call patch_1m_16m - xchgw %ax, %cx - xchgw %bx, %dx - call patch_1m_16m - xchgw %ax, %cx - xchgw %bx, %dx - popw %ds - iret - .size int15_e801, . - int15_e801 - -/**************************************************************************** - * INT 15,88 handler - **************************************************************************** - */ - .section ".text16", "ax", @progbits -int15_88: - /* Call previous handler */ - pushfw - lcall *%cs:int15_vector - call patch_cf - /* Edit result */ - pushw %ds - pushw %cs:rm_ds - popw %ds - call patch_1m - popw %ds - iret - .size int15_88, . - int15_88 - -/**************************************************************************** - * INT 15 handler - **************************************************************************** - */ - .section ".text16", "ax", @progbits - .globl int15 -int15: - /* See if we want to intercept this call */ - pushfw - cmpw $0xe820, %ax - jne 1f - cmpl $SMAP, %edx - jne 1f - popfw - jmp int15_e820 -1: cmpw $0xe801, %ax - jne 2f - popfw - jmp int15_e801 -2: cmpb $0x88, %ah - jne 3f - popfw - jmp int15_88 -3: popfw - ljmp *%cs:int15_vector - .size int15, . - int15 - - .section ".text16.data", "aw", @progbits - .globl int15_vector -int15_vector: - .long 0 - .size int15_vector, . - int15_vector diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/fakee820.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/fakee820.c deleted file mode 100644 index 15f4d772f..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/fakee820.c +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * 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 <realmode.h> -#include <biosint.h> - -/** Assembly routine in inline asm */ -extern void int15_fakee820(); - -/** Original INT 15 handler */ -static struct segoff __text16 ( real_int15_vector ); -#define real_int15_vector __use_text16 ( real_int15_vector ) - -/** An INT 15,e820 memory map entry */ -struct e820_entry { - /** Start of region */ - uint64_t start; - /** Length of region */ - uint64_t len; - /** Type of region */ - uint32_t type; -} __attribute__ (( packed )); - -#define E820_TYPE_RAM 1 /**< Normal memory */ -#define E820_TYPE_RSVD 2 /**< Reserved and unavailable */ -#define E820_TYPE_ACPI 3 /**< ACPI reclaim memory */ -#define E820_TYPE_NVS 4 /**< ACPI NVS memory */ - -/** Fake e820 map */ -static struct e820_entry __text16_array ( e820map, [] ) __used = { - { 0x00000000ULL, ( 0x000a0000ULL - 0x00000000ULL ), E820_TYPE_RAM }, - { 0x00100000ULL, ( 0xcfb50000ULL - 0x00100000ULL ), E820_TYPE_RAM }, - { 0xcfb50000ULL, ( 0xcfb64000ULL - 0xcfb50000ULL ), E820_TYPE_RSVD }, - { 0xcfb64000ULL, ( 0xcfb66000ULL - 0xcfb64000ULL ), E820_TYPE_RSVD }, - { 0xcfb66000ULL, ( 0xcfb85c00ULL - 0xcfb66000ULL ), E820_TYPE_ACPI }, - { 0xcfb85c00ULL, ( 0xd0000000ULL - 0xcfb85c00ULL ), E820_TYPE_RSVD }, - { 0xe0000000ULL, ( 0xf0000000ULL - 0xe0000000ULL ), E820_TYPE_RSVD }, - { 0xfe000000ULL, (0x100000000ULL - 0xfe000000ULL ), E820_TYPE_RSVD }, - {0x100000000ULL, (0x230000000ULL -0x100000000ULL ), E820_TYPE_RAM }, -}; -#define e820map __use_text16 ( e820map ) - -void fake_e820 ( void ) { - __asm__ __volatile__ ( - TEXT16_CODE ( "\nint15_fakee820:\n\t" - "pushfw\n\t" - "cmpl $0xe820, %%eax\n\t" - "jne 99f\n\t" - "cmpl $0x534d4150, %%edx\n\t" - "jne 99f\n\t" - "pushaw\n\t" - "movw %%sp, %%bp\n\t" - "andb $~0x01, 22(%%bp)\n\t" /* Clear return CF */ - "leaw e820map(%%bx), %%si\n\t" - "cs rep movsb\n\t" - "popaw\n\t" - "movl %%edx, %%eax\n\t" - "addl $20, %%ebx\n\t" - "cmpl %0, %%ebx\n\t" - "jne 1f\n\t" - "xorl %%ebx,%%ebx\n\t" - "\n1:\n\t" - "popfw\n\t" - "iret\n\t" - "\n99:\n\t" - "popfw\n\t" - "ljmp *%%cs:real_int15_vector\n\t" ) - : : "i" ( sizeof ( e820map ) ) ); - - hook_bios_interrupt ( 0x15, ( unsigned int ) int15_fakee820, - &real_int15_vector ); -} - -void unfake_e820 ( void ) { - unhook_bios_interrupt ( 0x15, ( unsigned int ) int15_fakee820, - &real_int15_vector ); -} diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/hidemem.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/hidemem.c deleted file mode 100644 index 253c601ff..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/hidemem.c +++ /dev/null @@ -1,235 +0,0 @@ -/* Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * 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 <assert.h> -#include <realmode.h> -#include <biosint.h> -#include <basemem.h> -#include <fakee820.h> -#include <ipxe/init.h> -#include <ipxe/io.h> -#include <ipxe/hidemem.h> - -/** Set to true if you want to test a fake E820 map */ -#define FAKE_E820 0 - -/** Alignment for hidden memory regions */ -#define ALIGN_HIDDEN 4096 /* 4kB page alignment should be enough */ - -/** - * A hidden region of iPXE - * - * This represents a region that will be edited out of the system's - * memory map. - * - * This structure is accessed by assembly code, so must not be - * changed. - */ -struct hidden_region { - /** Physical start address */ - uint64_t start; - /** Physical end address */ - uint64_t end; -}; - -/** Hidden base memory */ -extern struct hidden_region __data16 ( hidemem_base ); -#define hidemem_base __use_data16 ( hidemem_base ) - -/** Hidden umalloc memory */ -extern struct hidden_region __data16 ( hidemem_umalloc ); -#define hidemem_umalloc __use_data16 ( hidemem_umalloc ) - -/** Hidden text memory */ -extern struct hidden_region __data16 ( hidemem_textdata ); -#define hidemem_textdata __use_data16 ( hidemem_textdata ) - -/** Assembly routine in e820mangler.S */ -extern void int15(); - -/** Vector for storing original INT 15 handler */ -extern struct segoff __text16 ( int15_vector ); -#define int15_vector __use_text16 ( int15_vector ) - -/* The linker defines these symbols for us */ -extern char _textdata[]; -extern char _etextdata[]; -extern char _text16_memsz[]; -#define _text16_memsz ( ( unsigned int ) _text16_memsz ) -extern char _data16_memsz[]; -#define _data16_memsz ( ( unsigned int ) _data16_memsz ) - -/** - * Hide region of memory from system memory map - * - * @v region Hidden memory region - * @v start Start of region - * @v end End of region - */ -static void hide_region ( struct hidden_region *region, - physaddr_t start, physaddr_t end ) { - - /* Some operating systems get a nasty shock if a region of the - * E820 map seems to start on a non-page boundary. Make life - * safer by rounding out our edited region. - */ - region->start = ( start & ~( ALIGN_HIDDEN - 1 ) ); - region->end = ( ( end + ALIGN_HIDDEN - 1 ) & ~( ALIGN_HIDDEN - 1 ) ); - - DBG ( "Hiding region [%llx,%llx)\n", region->start, region->end ); -} - -/** - * Hide used base memory - * - */ -void hide_basemem ( void ) { - /* Hide from the top of free base memory to 640kB. Don't use - * hide_region(), because we don't want this rounded to the - * nearest page boundary. - */ - hidemem_base.start = ( get_fbms() * 1024 ); -} - -/** - * Hide umalloc() region - * - */ -void hide_umalloc ( physaddr_t start, physaddr_t end ) { - assert ( end <= virt_to_phys ( _textdata ) ); - hide_region ( &hidemem_umalloc, start, end ); -} - -/** - * Hide .text and .data - * - */ -void hide_textdata ( void ) { - hide_region ( &hidemem_textdata, virt_to_phys ( _textdata ), - virt_to_phys ( _etextdata ) ); -} - -/** - * Hide Etherboot - * - * Installs an INT 15 handler to edit Etherboot out of the memory map - * returned by the BIOS. - */ -static void hide_etherboot ( void ) { - struct memory_map memmap; - unsigned int rm_ds_top; - unsigned int rm_cs_top; - unsigned int fbms; - - /* Dump memory map before mangling */ - DBG ( "Hiding iPXE from system memory map\n" ); - get_memmap ( &memmap ); - - /* Hook in fake E820 map, if we're testing one */ - if ( FAKE_E820 ) { - DBG ( "Hooking in fake E820 map\n" ); - fake_e820(); - get_memmap ( &memmap ); - } - - /* Initialise the hidden regions */ - hide_basemem(); - hide_umalloc ( virt_to_phys ( _textdata ), virt_to_phys ( _textdata ) ); - hide_textdata(); - - /* Some really moronic BIOSes bring up the PXE stack via the - * UNDI loader entry point and then don't bother to unload it - * before overwriting the code and data segments. If this - * happens, we really don't want to leave INT 15 hooked, - * because that will cause any loaded OS to die horribly as - * soon as it attempts to fetch the system memory map. - * - * We use a heuristic to guess whether or not we are being - * loaded sensibly. - */ - rm_cs_top = ( ( ( rm_cs << 4 ) + _text16_memsz + 1024 - 1 ) >> 10 ); - rm_ds_top = ( ( ( rm_ds << 4 ) + _data16_memsz + 1024 - 1 ) >> 10 ); - fbms = get_fbms(); - if ( ( rm_cs_top < fbms ) && ( rm_ds_top < fbms ) ) { - DBG ( "Detected potentially unsafe UNDI load at CS=%04x " - "DS=%04x FBMS=%dkB\n", rm_cs, rm_ds, fbms ); - DBG ( "Disabling INT 15 memory hiding\n" ); - return; - } - - /* Hook INT 15 */ - hook_bios_interrupt ( 0x15, ( unsigned int ) int15, - &int15_vector ); - - /* Dump memory map after mangling */ - DBG ( "Hidden iPXE from system memory map\n" ); - get_memmap ( &memmap ); -} - -/** - * Unhide Etherboot - * - * Uninstalls the INT 15 handler installed by hide_etherboot(), if - * possible. - */ -static void unhide_etherboot ( int flags __unused ) { - struct memory_map memmap; - int rc; - - /* If we have more than one hooked interrupt at this point, it - * means that some other vector is still hooked, in which case - * we can't safely unhook INT 15 because we need to keep our - * memory protected. (We expect there to be at least one - * hooked interrupt, because INT 15 itself is still hooked). - */ - if ( hooked_bios_interrupts > 1 ) { - DBG ( "Cannot unhide: %d interrupt vectors still hooked\n", - hooked_bios_interrupts ); - return; - } - - /* Try to unhook INT 15 */ - if ( ( rc = unhook_bios_interrupt ( 0x15, ( unsigned int ) int15, - &int15_vector ) ) != 0 ) { - DBG ( "Cannot unhook INT15: %s\n", strerror ( rc ) ); - /* Leave it hooked; there's nothing else we can do, - * and it should be intrinsically safe (though - * wasteful of RAM). - */ - } - - /* Unhook fake E820 map, if used */ - if ( FAKE_E820 ) - unfake_e820(); - - /* Dump memory map after unhiding */ - DBG ( "Unhidden iPXE from system memory map\n" ); - get_memmap ( &memmap ); -} - -/** Hide Etherboot startup function */ -struct startup_fn hide_etherboot_startup_fn __startup_fn ( STARTUP_EARLY ) = { - .startup = hide_etherboot, - .shutdown = unhide_etherboot, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/memmap.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/memmap.c deleted file mode 100644 index bcacecd6a..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/memmap.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * 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 <errno.h> -#include <realmode.h> -#include <bios.h> -#include <memsizes.h> -#include <ipxe/io.h> - -/** - * @file - * - * Memory mapping - * - */ - -/** Magic value for INT 15,e820 calls */ -#define SMAP ( 0x534d4150 ) - -/** An INT 15,e820 memory map entry */ -struct e820_entry { - /** Start of region */ - uint64_t start; - /** Length of region */ - uint64_t len; - /** Type of region */ - uint32_t type; - /** Extended attributes (optional) */ - uint32_t attrs; -} __attribute__ (( packed )); - -#define E820_TYPE_RAM 1 /**< Normal memory */ -#define E820_TYPE_RESERVED 2 /**< Reserved and unavailable */ -#define E820_TYPE_ACPI 3 /**< ACPI reclaim memory */ -#define E820_TYPE_NVS 4 /**< ACPI NVS memory */ - -#define E820_ATTR_ENABLED 0x00000001UL -#define E820_ATTR_NONVOLATILE 0x00000002UL -#define E820_ATTR_UNKNOWN 0xfffffffcUL - -#define E820_MIN_SIZE 20 - -/** Buffer for INT 15,e820 calls */ -static struct e820_entry __bss16 ( e820buf ); -#define e820buf __use_data16 ( e820buf ) - -/** We are running during POST; inhibit INT 15,e820 and INT 15,e801 */ -uint8_t __bss16 ( memmap_post ); -#define memmap_post __use_data16 ( memmap_post ) - -/** - * Get size of extended memory via INT 15,e801 - * - * @ret extmem Extended memory size, in kB, or 0 - */ -static unsigned int extmemsize_e801 ( void ) { - uint16_t extmem_1m_to_16m_k, extmem_16m_plus_64k; - uint16_t confmem_1m_to_16m_k, confmem_16m_plus_64k; - unsigned int flags; - unsigned int extmem; - - /* Inhibit INT 15,e801 during POST */ - if ( memmap_post ) { - DBG ( "INT 15,e801 not available during POST\n" ); - return 0; - } - - __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" - "int $0x15\n\t" - "pushfw\n\t" - "popw %w0\n\t" ) - : "=r" ( flags ), - "=a" ( extmem_1m_to_16m_k ), - "=b" ( extmem_16m_plus_64k ), - "=c" ( confmem_1m_to_16m_k ), - "=d" ( confmem_16m_plus_64k ) - : "a" ( 0xe801 ) ); - - if ( flags & CF ) { - DBG ( "INT 15,e801 failed with CF set\n" ); - return 0; - } - - if ( ! ( extmem_1m_to_16m_k | extmem_16m_plus_64k ) ) { - DBG ( "INT 15,e801 extmem=0, using confmem\n" ); - extmem_1m_to_16m_k = confmem_1m_to_16m_k; - extmem_16m_plus_64k = confmem_16m_plus_64k; - } - - extmem = ( extmem_1m_to_16m_k + ( extmem_16m_plus_64k * 64 ) ); - DBG ( "INT 15,e801 extended memory size %d+64*%d=%d kB " - "[100000,%llx)\n", extmem_1m_to_16m_k, extmem_16m_plus_64k, - extmem, ( 0x100000 + ( ( ( uint64_t ) extmem ) * 1024 ) ) ); - - /* Sanity check. Some BIOSes report the entire 4GB address - * space as available, which cannot be correct (since that - * would leave no address space available for 32-bit PCI - * BARs). - */ - if ( extmem == ( 0x400000 - 0x400 ) ) { - DBG ( "INT 15,e801 reported whole 4GB; assuming insane\n" ); - return 0; - } - - return extmem; -} - -/** - * Get size of extended memory via INT 15,88 - * - * @ret extmem Extended memory size, in kB - */ -static unsigned int extmemsize_88 ( void ) { - uint16_t extmem; - - /* Ignore CF; it is not reliable for this call */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x15" ) - : "=a" ( extmem ) : "a" ( 0x8800 ) ); - - DBG ( "INT 15,88 extended memory size %d kB [100000, %x)\n", - extmem, ( 0x100000 + ( extmem * 1024 ) ) ); - return extmem; -} - -/** - * Get size of extended memory - * - * @ret extmem Extended memory size, in kB - * - * Note that this is only an approximation; for an accurate picture, - * use the E820 memory map obtained via get_memmap(); - */ -unsigned int extmemsize ( void ) { - unsigned int extmem_e801; - unsigned int extmem_88; - - /* Try INT 15,e801 first, then fall back to INT 15,88 */ - extmem_88 = extmemsize_88(); - extmem_e801 = extmemsize_e801(); - return ( extmem_e801 ? extmem_e801 : extmem_88 ); -} - -/** - * Get e820 memory map - * - * @v memmap Memory map to fill in - * @ret rc Return status code - */ -static int meme820 ( struct memory_map *memmap ) { - struct memory_region *region = memmap->regions; - struct memory_region *prev_region = NULL; - uint32_t next = 0; - uint32_t smap; - size_t size; - unsigned int flags; - unsigned int discard_D; - - /* Inhibit INT 15,e820 during POST */ - if ( memmap_post ) { - DBG ( "INT 15,e820 not available during POST\n" ); - return -ENOTTY; - } - - /* Clear the E820 buffer. Do this once before starting, - * rather than on each call; some BIOSes rely on the contents - * being preserved between calls. - */ - memset ( &e820buf, 0, sizeof ( e820buf ) ); - - do { - /* Some BIOSes corrupt %esi for fun. Guard against - * this by telling gcc that all non-output registers - * may be corrupted. - */ - __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" - "stc\n\t" - "int $0x15\n\t" - "pushfw\n\t" - "popw %%dx\n\t" - "popl %%ebp\n\t" ) - : "=a" ( smap ), "=b" ( next ), - "=c" ( size ), "=d" ( flags ), - "=D" ( discard_D ) - : "a" ( 0xe820 ), "b" ( next ), - "D" ( __from_data16 ( &e820buf ) ), - "c" ( sizeof ( e820buf ) ), - "d" ( SMAP ) - : "esi", "memory" ); - - if ( smap != SMAP ) { - DBG ( "INT 15,e820 failed SMAP signature check\n" ); - return -ENOTSUP; - } - - if ( size < E820_MIN_SIZE ) { - DBG ( "INT 15,e820 returned only %zd bytes\n", size ); - return -EINVAL; - } - - if ( flags & CF ) { - DBG ( "INT 15,e820 terminated on CF set\n" ); - break; - } - - /* If first region is not RAM, assume map is invalid */ - if ( ( memmap->count == 0 ) && - ( e820buf.type != E820_TYPE_RAM ) ) { - DBG ( "INT 15,e820 failed, first entry not RAM\n" ); - return -EINVAL; - } - - DBG ( "INT 15,e820 region [%llx,%llx) type %d", - e820buf.start, ( e820buf.start + e820buf.len ), - ( int ) e820buf.type ); - if ( size > offsetof ( typeof ( e820buf ), attrs ) ) { - DBG ( " (%s", ( ( e820buf.attrs & E820_ATTR_ENABLED ) - ? "enabled" : "disabled" ) ); - if ( e820buf.attrs & E820_ATTR_NONVOLATILE ) - DBG ( ", non-volatile" ); - if ( e820buf.attrs & E820_ATTR_UNKNOWN ) - DBG ( ", other [%08x]", e820buf.attrs ); - DBG ( ")" ); - } - DBG ( "\n" ); - - /* Discard non-RAM regions */ - if ( e820buf.type != E820_TYPE_RAM ) - continue; - - /* Check extended attributes, if present */ - if ( size > offsetof ( typeof ( e820buf ), attrs ) ) { - if ( ! ( e820buf.attrs & E820_ATTR_ENABLED ) ) - continue; - if ( e820buf.attrs & E820_ATTR_NONVOLATILE ) - continue; - } - - region->start = e820buf.start; - region->end = e820buf.start + e820buf.len; - - /* Check for adjacent regions and merge them */ - if ( prev_region && ( region->start == prev_region->end ) ) { - prev_region->end = region->end; - } else { - prev_region = region; - region++; - memmap->count++; - } - - if ( memmap->count >= ( sizeof ( memmap->regions ) / - sizeof ( memmap->regions[0] ) ) ) { - DBG ( "INT 15,e820 too many regions returned\n" ); - /* Not a fatal error; what we've got so far at - * least represents valid regions of memory, - * even if we couldn't get them all. - */ - break; - } - } while ( next != 0 ); - - /* Sanity checks. Some BIOSes report complete garbage via INT - * 15,e820 (especially at POST time), despite passing the - * signature checks. We currently check for a base memory - * region (starting at 0) and at least one high memory region - * (starting at 0x100000). - */ - if ( memmap->count < 2 ) { - DBG ( "INT 15,e820 returned only %d regions; assuming " - "insane\n", memmap->count ); - return -EINVAL; - } - if ( memmap->regions[0].start != 0 ) { - DBG ( "INT 15,e820 region 0 starts at %llx (expected 0); " - "assuming insane\n", memmap->regions[0].start ); - return -EINVAL; - } - if ( memmap->regions[1].start != 0x100000 ) { - DBG ( "INT 15,e820 region 1 starts at %llx (expected 100000); " - "assuming insane\n", memmap->regions[0].start ); - return -EINVAL; - } - - return 0; -} - -/** - * Get memory map - * - * @v memmap Memory map to fill in - */ -void x86_get_memmap ( struct memory_map *memmap ) { - unsigned int basemem, extmem; - int rc; - - DBG ( "Fetching system memory map\n" ); - - /* Clear memory map */ - memset ( memmap, 0, sizeof ( *memmap ) ); - - /* Get base and extended memory sizes */ - basemem = basememsize(); - DBG ( "FBMS base memory size %d kB [0,%x)\n", - basemem, ( basemem * 1024 ) ); - extmem = extmemsize(); - - /* Try INT 15,e820 first */ - if ( ( rc = meme820 ( memmap ) ) == 0 ) { - DBG ( "Obtained system memory map via INT 15,e820\n" ); - return; - } - - /* Fall back to constructing a map from basemem and extmem sizes */ - DBG ( "INT 15,e820 failed; constructing map\n" ); - memmap->regions[0].end = ( basemem * 1024 ); - memmap->regions[1].start = 0x100000; - memmap->regions[1].end = 0x100000 + ( extmem * 1024 ); - memmap->count = 2; -} - -PROVIDE_IOAPI ( x86, get_memmap, x86_get_memmap ); diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/pnpbios.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/pnpbios.c deleted file mode 100644 index 20ec35d75..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/pnpbios.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * 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 <realmode.h> -#include <pnpbios.h> - -/** @file - * - * PnP BIOS - * - */ - -/** PnP BIOS structure */ -struct pnp_bios { - /** Signature - * - * Must be equal to @c PNP_BIOS_SIGNATURE - */ - uint32_t signature; - /** Version as BCD (e.g. 1.0 is 0x10) */ - uint8_t version; - /** Length of this structure */ - uint8_t length; - /** System capabilities */ - uint16_t control; - /** Checksum */ - uint8_t checksum; -} __attribute__ (( packed )); - -/** Signature for a PnP BIOS structure */ -#define PNP_BIOS_SIGNATURE \ - ( ( '$' << 0 ) + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) ) - -/** - * Test address for PnP BIOS structure - * - * @v offset Offset within BIOS segment to test - * @ret rc Return status code - */ -static int is_pnp_bios ( unsigned int offset ) { - union { - struct pnp_bios pnp_bios; - uint8_t bytes[256]; /* 256 is maximum length possible */ - } u; - size_t len; - unsigned int i; - uint8_t sum = 0; - - /* Read start of header and verify signature */ - copy_from_real ( &u.pnp_bios, BIOS_SEG, offset, sizeof ( u.pnp_bios )); - if ( u.pnp_bios.signature != PNP_BIOS_SIGNATURE ) - return -EINVAL; - - /* Read whole header and verify checksum */ - len = u.pnp_bios.length; - copy_from_real ( &u.bytes, BIOS_SEG, offset, len ); - for ( i = 0 ; i < len ; i++ ) { - sum += u.bytes[i]; - } - if ( sum != 0 ) - return -EINVAL; - - DBG ( "Found PnP BIOS at %04x:%04x\n", BIOS_SEG, offset ); - - return 0; -} - -/** - * Locate Plug-and-Play BIOS - * - * @ret pnp_offset Offset of PnP BIOS structure within BIOS segment - * - * The PnP BIOS structure will be at BIOS_SEG:pnp_offset. If no PnP - * BIOS is found, -1 is returned. - */ -int find_pnp_bios ( void ) { - static int pnp_offset = 0; - - if ( pnp_offset ) - return pnp_offset; - - for ( pnp_offset = 0 ; pnp_offset < 0x10000 ; pnp_offset += 0x10 ) { - if ( is_pnp_bios ( pnp_offset ) == 0 ) - return pnp_offset; - } - - pnp_offset = -1; - return pnp_offset; -} |