Pārlūkot izejas kodu

[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 gadus atpakaļ
vecāks
revīzija
c24bc349ea

+ 90
- 0
src/arch/i386/firmware/pcbios/fakee820.c Parādīt failu

@@ -0,0 +1,90 @@
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 Parādīt failu

@@ -19,10 +19,14 @@
19 19
 #include <realmode.h>
20 20
 #include <biosint.h>
21 21
 #include <basemem.h>
22
+#include <fakee820.h>
22 23
 #include <gpxe/init.h>
23 24
 #include <gpxe/memmap.h>
24 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 30
 /** Alignment for hidden memory regions */
27 31
 #define ALIGN_HIDDEN 4096   /* 4kB page alignment should be enough */
28 32
 
@@ -135,6 +139,13 @@ static void hide_etherboot ( void ) {
135 139
 	DBG ( "Hiding gPXE from system memory map\n" );
136 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 149
 	/* Initialise the hidden regions */
139 150
 	hide_basemem();
140 151
 	hide_umalloc ( virt_to_phys ( _text ), virt_to_phys ( _text ) );
@@ -194,6 +205,10 @@ static void unhide_etherboot ( int flags __unused ) {
194 205
 	 */
195 206
 	unhook_bios_interrupt ( 0x15, ( unsigned int ) int15,
196 207
 				&int15_vector );
208
+
209
+	/* Unhook fake E820 map, if used */
210
+	if ( FAKE_E820 )
211
+		unfake_e820();
197 212
 }
198 213
 
199 214
 /** Hide Etherboot startup function */

+ 7
- 0
src/arch/i386/include/fakee820.h Parādīt failu

@@ -0,0 +1,7 @@
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 */

Notiek ielāde…
Atcelt
Saglabāt