瀏覽代碼

[pcbios] Add facility for testing arbitrary E820 memory maps

We seem to be having issues with various E820 memory maps.  These
problems are often difficult to reproduce, requiring access to the
specific system exhibiting the problem.

Add a facility for hooking in a fake E820 map generator, using an
arbitrary map defined in a C array, solely in order to be able to test
the map-mangling code against arbitrary E820 maps.
tags/v0.9.4
Michael Brown 15 年之前
父節點
當前提交
c24bc349ea
共有 3 個文件被更改,包括 112 次插入0 次删除
  1. 90
    0
      src/arch/i386/firmware/pcbios/fakee820.c
  2. 15
    0
      src/arch/i386/firmware/pcbios/hidemem.c
  3. 7
    0
      src/arch/i386/include/fakee820.h

+ 90
- 0
src/arch/i386/firmware/pcbios/fakee820.c 查看文件

1
+/* Copyright (C) 2008 Michael Brown <mbrown@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
+#include <realmode.h>
19
+#include <biosint.h>
20
+
21
+/** Assembly routine in inline asm */
22
+extern void int15_fakee820();
23
+
24
+/** Original INT 15 handler */
25
+static struct segoff __text16 ( real_int15_vector );
26
+#define real_int15_vector __use_text16 ( real_int15_vector )
27
+
28
+/** An INT 15,e820 memory map entry */
29
+struct e820_entry {
30
+	/** Start of region */
31
+	uint64_t start;
32
+	/** Length of region */
33
+	uint64_t len;
34
+	/** Type of region */
35
+	uint32_t type;
36
+} __attribute__ (( packed ));
37
+
38
+#define E820_TYPE_RAM		1 /**< Normal memory */
39
+#define E820_TYPE_RSVD		2 /**< Reserved and unavailable */
40
+#define E820_TYPE_ACPI		3 /**< ACPI reclaim memory */
41
+#define E820_TYPE_NVS		4 /**< ACPI NVS memory */
42
+
43
+/** Fake e820 map */
44
+static struct e820_entry __text16_array ( e820map, [] ) __used = {
45
+	{ 0x00000000ULL, ( 0x000a0000ULL - 0x00000000ULL ), E820_TYPE_RAM },
46
+	{ 0x00100000ULL, ( 0xcfb50000ULL - 0x00100000ULL ), E820_TYPE_RAM },
47
+	{ 0xcfb50000ULL, ( 0xcfb64000ULL - 0xcfb50000ULL ), E820_TYPE_RSVD },
48
+	{ 0xcfb64000ULL, ( 0xcfb66000ULL - 0xcfb64000ULL ), E820_TYPE_RSVD },
49
+	{ 0xcfb66000ULL, ( 0xcfb85c00ULL - 0xcfb66000ULL ), E820_TYPE_ACPI },
50
+	{ 0xcfb85c00ULL, ( 0xd0000000ULL - 0xcfb85c00ULL ), E820_TYPE_RSVD },
51
+	{ 0xe0000000ULL, ( 0xf0000000ULL - 0xe0000000ULL ), E820_TYPE_RSVD },
52
+	{ 0xfe000000ULL, (0x100000000ULL - 0xfe000000ULL ), E820_TYPE_RSVD },
53
+	{0x100000000ULL, (0x230000000ULL -0x100000000ULL ), E820_TYPE_RAM },
54
+};
55
+#define e820map __use_text16 ( e820map )
56
+
57
+void fake_e820 ( void ) {
58
+	__asm__ __volatile__ (
59
+		TEXT16_CODE ( "\nint15_fakee820:\n\t"
60
+			      "pushfw\n\t"
61
+			      "cmpl $0xe820, %%eax\n\t"
62
+			      "jne 99f\n\t"
63
+			      "cmpl $0x534d4150, %%edx\n\t"
64
+			      "jne 99f\n\t"
65
+			      "pushaw\n\t"
66
+			      "leaw e820map(%%bx), %%si\n\t"
67
+			      "cs rep movsb\n\t"
68
+			      "popaw\n\t"
69
+			      "movl %%edx, %%eax\n\t"
70
+			      "addl $20, %%ebx\n\t"
71
+			      "cmpl %0, %%ebx\n\t"
72
+			      "jne 1f\n\t"
73
+			      "xorl %%ebx,%%ebx\n\t"
74
+			      "\n1:\n\t"
75
+			      "popfw\n\t"
76
+			      "clc\n\t"
77
+			      "lret $2\n\t"
78
+			      "\n99:\n\t"
79
+			      "popfw\n\t"
80
+			      "ljmp *%%cs:real_int15_vector\n\t" )
81
+		: : "i" ( sizeof ( e820map ) ) );
82
+
83
+	hook_bios_interrupt ( 0x15, ( unsigned int ) int15_fakee820,
84
+			      &real_int15_vector );
85
+}
86
+
87
+void unfake_e820 ( void ) {
88
+	unhook_bios_interrupt ( 0x15, ( unsigned int ) int15_fakee820,
89
+				&real_int15_vector );
90
+}

+ 15
- 0
src/arch/i386/firmware/pcbios/hidemem.c 查看文件

19
 #include <realmode.h>
19
 #include <realmode.h>
20
 #include <biosint.h>
20
 #include <biosint.h>
21
 #include <basemem.h>
21
 #include <basemem.h>
22
+#include <fakee820.h>
22
 #include <gpxe/init.h>
23
 #include <gpxe/init.h>
23
 #include <gpxe/memmap.h>
24
 #include <gpxe/memmap.h>
24
 #include <gpxe/hidemem.h>
25
 #include <gpxe/hidemem.h>
25
 
26
 
27
+/** Set to true if you want to test a fake E820 map */
28
+#define FAKE_E820 0
29
+
26
 /** Alignment for hidden memory regions */
30
 /** Alignment for hidden memory regions */
27
 #define ALIGN_HIDDEN 4096   /* 4kB page alignment should be enough */
31
 #define ALIGN_HIDDEN 4096   /* 4kB page alignment should be enough */
28
 
32
 
135
 	DBG ( "Hiding gPXE from system memory map\n" );
139
 	DBG ( "Hiding gPXE from system memory map\n" );
136
 	get_memmap ( &memmap );
140
 	get_memmap ( &memmap );
137
 
141
 
142
+	/* Hook in fake E820 map, if we're testing one */
143
+	if ( FAKE_E820 ) {
144
+		DBG ( "Hooking in fake E820 map\n" );
145
+		fake_e820();
146
+		get_memmap ( &memmap );
147
+	}
148
+
138
 	/* Initialise the hidden regions */
149
 	/* Initialise the hidden regions */
139
 	hide_basemem();
150
 	hide_basemem();
140
 	hide_umalloc ( virt_to_phys ( _text ), virt_to_phys ( _text ) );
151
 	hide_umalloc ( virt_to_phys ( _text ), virt_to_phys ( _text ) );
194
 	 */
205
 	 */
195
 	unhook_bios_interrupt ( 0x15, ( unsigned int ) int15,
206
 	unhook_bios_interrupt ( 0x15, ( unsigned int ) int15,
196
 				&int15_vector );
207
 				&int15_vector );
208
+
209
+	/* Unhook fake E820 map, if used */
210
+	if ( FAKE_E820 )
211
+		unfake_e820();
197
 }
212
 }
198
 
213
 
199
 /** Hide Etherboot startup function */
214
 /** Hide Etherboot startup function */

+ 7
- 0
src/arch/i386/include/fakee820.h 查看文件

1
+#ifndef _FAKEE820_H
2
+#define _FAKEE820_H
3
+
4
+extern void fake_e820 ( void );
5
+extern void unfake_e820 ( void );
6
+
7
+#endif /* _FAKEE820_H */

Loading…
取消
儲存