1 /* Copyright (C) 2008 Michael Brown <mbrown (at) fensystems.co.uk>. 2 * 3 * This program is free software; you can redistribute it and/or 4 * modify it under the terms of the GNU General Public License as 5 * published by the Free Software Foundation; either version 2 of the 6 * License, or any later version. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 */ 17 18 FILE_LICENCE ( GPL2_OR_LATER ); 19 20 #include <realmode.h> 21 #include <biosint.h> 22 23 /** Assembly routine in inline asm */ 24 extern void int15_fakee820(); 25 26 /** Original INT 15 handler */ 27 static struct segoff __text16 ( real_int15_vector ); 28 #define real_int15_vector __use_text16 ( real_int15_vector ) 29 30 /** An INT 15,e820 memory map entry */ 31 struct e820_entry { 32 /** Start of region */ 33 uint64_t start; 34 /** Length of region */ 35 uint64_t len; 36 /** Type of region */ 37 uint32_t type; 38 } __attribute__ (( packed )); 39 40 #define E820_TYPE_RAM 1 /**< Normal memory */ 41 #define E820_TYPE_RSVD 2 /**< Reserved and unavailable */ 42 #define E820_TYPE_ACPI 3 /**< ACPI reclaim memory */ 43 #define E820_TYPE_NVS 4 /**< ACPI NVS memory */ 44 45 /** Fake e820 map */ 46 static struct e820_entry __text16_array ( e820map, [] ) __used = { 47 { 0x00000000ULL, ( 0x000a0000ULL - 0x00000000ULL ), E820_TYPE_RAM }, 48 { 0x00100000ULL, ( 0xcfb50000ULL - 0x00100000ULL ), E820_TYPE_RAM }, 49 { 0xcfb50000ULL, ( 0xcfb64000ULL - 0xcfb50000ULL ), E820_TYPE_RSVD }, 50 { 0xcfb64000ULL, ( 0xcfb66000ULL - 0xcfb64000ULL ), E820_TYPE_RSVD }, 51 { 0xcfb66000ULL, ( 0xcfb85c00ULL - 0xcfb66000ULL ), E820_TYPE_ACPI }, 52 { 0xcfb85c00ULL, ( 0xd0000000ULL - 0xcfb85c00ULL ), E820_TYPE_RSVD }, 53 { 0xe0000000ULL, ( 0xf0000000ULL - 0xe0000000ULL ), E820_TYPE_RSVD }, 54 { 0xfe000000ULL, (0x100000000ULL - 0xfe000000ULL ), E820_TYPE_RSVD }, 55 {0x100000000ULL, (0x230000000ULL -0x100000000ULL ), E820_TYPE_RAM }, 56 }; 57 #define e820map __use_text16 ( e820map ) 58 59 void fake_e820 ( void ) { 60 __asm__ __volatile__ ( 61 TEXT16_CODE ( "\nint15_fakee820:\n\t" 62 "pushfw\n\t" 63 "cmpl $0xe820, %%eax\n\t" 64 "jne 99f\n\t" 65 "cmpl $0x534d4150, %%edx\n\t" 66 "jne 99f\n\t" 67 "pushaw\n\t" 68 "movw %%sp, %%bp\n\t" 69 "andb $~0x01, 22(%%bp)\n\t" /* Clear return CF */ 70 "leaw e820map(%%bx), %%si\n\t" 71 "cs rep movsb\n\t" 72 "popaw\n\t" 73 "movl %%edx, %%eax\n\t" 74 "addl $20, %%ebx\n\t" 75 "cmpl %0, %%ebx\n\t" 76 "jne 1f\n\t" 77 "xorl %%ebx,%%ebx\n\t" 78 "\n1:\n\t" 79 "popfw\n\t" 80 "iret\n\t" 81 "\n99:\n\t" 82 "popfw\n\t" 83 "ljmp *%%cs:real_int15_vector\n\t" ) 84 : : "i" ( sizeof ( e820map ) ) ); 85 86 hook_bios_interrupt ( 0x15, ( unsigned int ) int15_fakee820, 87 &real_int15_vector ); 88 } 89 90 void unfake_e820 ( void ) { 91 unhook_bios_interrupt ( 0x15, ( unsigned int ) int15_fakee820, 92 &real_int15_vector ); 93 } 94