Browse Source

Checking in obsolete but working memory-scanning code just for the record

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
075d79f6d4
1 changed files with 70 additions and 193 deletions
  1. 70
    193
      src/arch/i386/drivers/bus/pxebus.c

+ 70
- 193
src/arch/i386/drivers/bus/pxebus.c View File

@@ -1,3 +1,5 @@
1
+#if 0
2
+
1 3
 /*
2 4
  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3 5
  *
@@ -22,7 +24,10 @@
22 24
 #include <assert.h>
23 25
 #include <pxe.h>
24 26
 #include <realmode.h>
27
+#include <bios.h>
28
+#include <pnpbios.h>
25 29
 #include <gpxe/device.h>
30
+#include <gpxe/pci.h>
26 31
 
27 32
 /** @file
28 33
  *
@@ -30,84 +35,6 @@
30 35
  *
31 36
  */
32 37
 
33
-/**
34
- * UNDI parameter block
35
- *
36
- * Used as the paramter block for all UNDI API calls.  Resides in base
37
- * memory.
38
- */
39
-static union u_PXENV_ANY __data16 ( pxe_params );
40
-#define pxe_params __use_data16 ( pxe_params )
41
-
42
-/** UNDI entry point */
43
-static SEGOFF16_t __data16 ( pxe_entry_point );
44
-#define pxe_entry_point __use_data16 ( pxe_entry_point )
45
-
46
-/**
47
- * Issue PXE API call
48
- *
49
- * @v pxe		PXE device
50
- * @v function		API call number
51
- * @v params		PXE parameter block
52
- * @v params_len	Length of PXE parameter block
53
- * @ret rc		Return status code
54
- */
55
-int pxe_call ( struct pxe_device *pxe, unsigned int function,
56
-	       void *params, size_t params_len ) {
57
-	union u_PXENV_ANY *pxenv_any = params;
58
-	PXENV_EXIT_t exit;
59
-	int discard_b, discard_D;
60
-	int rc;
61
-
62
-	/* Copy parameter block and entry point */
63
-	assert ( params_len <= sizeof ( pxe_params ) );
64
-	memcpy ( &pxe_params, params, params_len );
65
-	pxe_entry_point = pxe->entry;
66
-
67
-	/* Call real-mode entry point.  This calling convention will
68
-	 * work with both the !PXE and the PXENV+ entry points.
69
-	 */
70
-	__asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t"
71
-					   "pushw %%di\n\t"
72
-					   "pushw %%bx\n\t"
73
-					   "lcall *%c3\n\t"
74
-					   "addw $6, %%sp\n\t" )
75
-			       : "=a" ( exit ), "=b" ( discard_b ),
76
-			         "=D" ( discard_D )
77
-			       : "p" ( & __from_data16 ( pxe_entry_point ) ),
78
-			         "b" ( function ),
79
-			         "D" ( & __from_data16 ( pxe_params ) ) );
80
-
81
-	/* UNDI API calls may rudely change the status of A20 and not
82
-	 * bother to restore it afterwards.  Intel is known to be
83
-	 * guilty of this.
84
-	 *
85
-	 * Note that we will return to this point even if A20 gets
86
-	 * screwed up by the UNDI driver, because Etherboot always
87
-	 * resides in an even megabyte of RAM.
88
-	 */	
89
-	gateA20_set();
90
-
91
-	/* Copy parameter block back */
92
-	memcpy ( params, &pxe_params, params_len );
93
-
94
-	/* Determine return status code based on PXENV_EXIT and
95
-	 * PXENV_STATUS
96
-	 */
97
-	if ( exit == PXENV_EXIT_SUCCESS ) {
98
-		rc = 0;
99
-	} else {
100
-		rc = -pxenv_any->Status;
101
-		/* Paranoia; don't return success for the combination
102
-		 * of PXENV_EXIT_FAILURE but PXENV_STATUS_SUCCESS
103
-		 */
104
-		if ( rc == 0 )
105
-			rc = -EIO;
106
-	}
107
-
108
-	return rc;
109
-}
110
-
111 38
 /**
112 39
  * Byte checksum
113 40
  *
@@ -125,82 +52,6 @@ static uint8_t checksum ( void *data, size_t len ) {
125 52
 	return sum;
126 53
 }
127 54
 
128
-/**
129
- * Get PXE device information for an instantiated device
130
- *
131
- * @v pxe		PXE device
132
- * @ret rc		Return status code
133
- */
134
-static int pxedev_get_instance_info ( struct pxe_device *pxe ) {
135
-	struct s_PXENV pxenv;
136
-	struct s_PXE ppxe;
137
-	struct s_PXENV_UNDI_GET_INFORMATION undi_info;
138
-	int rc;
139
-
140
-	/* Determine entry point from PXENV+ structure */
141
-	DBGC ( pxe, "PXE %p has PXENV+ structure at %04x:%04x\n", pxe,
142
-	      pxe->pxenv.segment, pxe->pxenv.offset );
143
-	copy_from_real ( &pxenv, pxe->pxenv.segment, pxe->pxenv.offset,
144
-			 sizeof ( pxenv ) );
145
-	if ( checksum ( &pxenv, sizeof ( pxenv ) ) != 0 ) {
146
-		DBGC ( pxe, "PXE %p bad PXENV+ checksum\n", pxe );
147
-		return -EINVAL;
148
-	}
149
-	pxe->entry = pxenv.RMEntry;
150
-
151
-	/* If API version is 2.1 or greater, use the !PXE structure instead */
152
-	if ( pxenv.Version >= 0x0201 ) {
153
-		pxe->ppxe = pxenv.PXEPtr;
154
-		DBGC ( pxe, "PXE %p has !PXE structure at %04x:%04x\n", pxe,
155
-		       pxe->ppxe.segment, pxe->ppxe.offset );
156
-		copy_from_real ( &ppxe, pxe->ppxe.segment, pxe->ppxe.offset,
157
-				 sizeof ( ppxe ) );
158
-		if ( checksum ( &pxenv, sizeof ( pxenv ) ) != 0 ) {
159
-			DBGC ( pxe, "PXE %p bad !PXE checksum\n", pxe );
160
-			return -EINVAL;
161
-		}
162
-		pxe->entry = ppxe.EntryPointSP;
163
-	}
164
-
165
-	DBGC ( pxe, "PXE %p using entry point at %04x:%04x\n", pxe,
166
-	       pxe->entry.segment, pxe->entry.offset );
167
-
168
-	/* Get device information */
169
-	memset ( &undi_info, 0, sizeof ( undi_info ) );
170
-	if ( ( rc = pxe_call ( pxe, PXENV_UNDI_GET_INFORMATION, &undi_info,
171
-			       sizeof ( undi_info ) ) ) != 0 ) {
172
-		DBGC ( pxe, "PXE %p could not retrieve UNDI information: %s\n",
173
-		       pxe, strerror ( rc ) );
174
-		return rc;
175
-	}
176
-	memcpy ( pxe->hwaddr, undi_info.PermNodeAddress,
177
-		 sizeof ( pxe->hwaddr ) );
178
-	pxe->irq = undi_info.IntNumber;
179
-	pxe->rom_segment = undi_info.ROMAddress;
180
-
181
-	return 0;
182
-}
183
-
184
-/**
185
- * Register PXE device
186
- *
187
- * @v pxe		PXE device
188
- * @ret rc		Return status code
189
- */
190
-static int register_pxedev ( struct pxe_device *pxe ) {
191
-	int rc;
192
-
193
-	DBGC ( pxe, "PXE %p registering\n", pxe );
194
-
195
-	/* Register as an UNDI driver */
196
-	if ( ( rc = undi_probe ( pxe ) ) != 0 )
197
-		return rc;
198
-
199
-	/* Add to device hierarchy and return */
200
-	list_add ( &pxe->dev.siblings, &pxe->dev.parent->children );
201
-	return 0;
202
-}
203
-
204 55
 /**
205 56
  * Unregister a PXE device
206 57
  *
@@ -224,47 +75,74 @@ static void pxebus_remove ( struct root_device *rootdev );
224 75
  * find.
225 76
  */
226 77
 static int pxebus_probe ( struct root_device *rootdev ) {
227
-	struct pxe_device *pxe;
228
-	uint16_t signature;
229
-	uint16_t pxenv_segment;
230
-	uint16_t pxenv_offset;
78
+	struct pxe_device *pxe = NULL;
79
+	struct s_PXENV pxenv;
80
+	struct s_PXE ppxe;
81
+	uint16_t fbms;
82
+	unsigned int segment;
83
+	unsigned int undi_cs;
231 84
 	int rc;
232 85
 
233
-	/* PXE installation check */
234
-	__asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
235
-					   "int $0x1a\n\t"
236
-					   "jnc 1f\n\t"
237
-					   "xorw %%ax, %%ax\n\t"
238
-					   "\n1:\n\t"
239
-					   "movw %%es, %%dx\n\t" )
240
-			       : "=a" ( signature ), "=b" ( pxenv_offset ),
241
-			         "=d" ( pxenv_segment )
242
-			       : "a" ( 0x5650 ) );
243
-	if ( signature != 0x564e ) {
244
-		DBG ( "No pixies found\n" );
245
-		return 0;
246
-	}
247
-
248
-	/* Allocate PXE device structure */
249
-	pxe = malloc ( sizeof ( *pxe ) );
250
-	if ( ! pxe ) {
251
-		rc = -ENOMEM;
252
-		goto err;
253
-	}
254
-	memset ( pxe, 0, sizeof ( *pxe ) );
86
+	/* Scan through allocated base memory for PXENV+ structure */
87
+	get_real ( fbms, BDA_SEG, BDA_FBMS );
88
+	for ( segment = ( fbms << 6 ) ; segment < 0xa000 ; segment++ ) {
255 89
 
256
-	/* Populate PXE device structure */
257
-	pxe->pxenv.segment = pxenv_segment;
258
-	pxe->pxenv.offset = pxenv_offset;
259
-	INIT_LIST_HEAD ( &pxe->dev.children );
260
-	pxe->dev.parent = &rootdev->dev;
261
-	if ( ( rc = pxedev_get_instance_info ( pxe ) ) != 0 )
262
-		goto err;
90
+		/* Verify PXENV+ signature and checksum */
91
+		copy_from_real ( &pxenv, segment, 0, sizeof ( pxenv ) );
92
+		if ( memcmp ( pxenv.Signature, "PXENV+", 6 ) != 0 )
93
+			continue;
94
+		DBG ( "Found PXENV+ signature at %04x0\n", segment );
95
+		if ( checksum ( &pxenv, sizeof ( pxenv ) ) != 0 ) {
96
+			DBG ( "...bad checksum\n" );
97
+			continue;
98
+		}
263 99
 
264
-	/* Register PXE device */
265
-	if ( ( rc = register_pxedev ( pxe ) ) != 0 )
266
-		goto err;
100
+		/* Allocate PXE device structure */
101
+		pxe = malloc ( sizeof ( *pxe ) );
102
+		if ( ! pxe ) {
103
+			rc = -ENOMEM;
104
+			goto err;
105
+		}
106
+		memset ( pxe, 0, sizeof ( *pxe ) );
107
+
108
+		/* Add to device hierarchy */
109
+		pxe->dev.parent = &rootdev->dev;
110
+		INIT_LIST_HEAD ( &pxe->dev.children );
111
+		list_add ( &pxe->dev.siblings, &rootdev->dev.children );
112
+
113
+		/* Populate PXE device structure */
114
+		undi_cs = pxenv.UNDICodeSeg;
115
+		pxe->pxenv.segment = undi_cs;
116
+		pxe->pxenv.offset = ( ( segment - undi_cs ) << 4 );
117
+		DBGC ( pxe, "PXE %p has PXENV+ structure at %04x:%04x\n",
118
+		       pxe, pxe->pxenv.segment, pxe->pxenv.offset );
119
+		pxe->entry = pxenv.RMEntry;
120
+		if ( pxenv.Version >= 0x0201 ) {
121
+			pxe->ppxe = pxenv.PXEPtr;
122
+			copy_from_real ( &ppxe, pxe->ppxe.segment,
123
+					 pxe->ppxe.offset, sizeof ( ppxe ) );
124
+			if ( ( memcmp ( ppxe.Signature, "!PXE", 4 ) == 0 ) &&
125
+			     ( checksum ( &ppxe, sizeof ( ppxe ) ) == 0 ) ) {
126
+				DBGC ( pxe, "PXE %p has !PXE structure at "
127
+				       "%04x:%04x\n", pxe,
128
+				       pxe->ppxe.segment, pxe->ppxe.offset );
129
+				pxe->entry = ppxe.EntryPointSP;
130
+			}
131
+		}
132
+		DBGC ( pxe, "PXE %p using entry point at %04x:%04x\n", pxe,
133
+		       pxe->entry.segment, pxe->entry.offset );
134
+
135
+		/* Register PXE device */
136
+		if ( undi_probe ( pxe ) == 0 ) {
137
+			/* Device registered; drop reference */
138
+			pxe = NULL;
139
+		} else {
140
+			/* Not registered; re-use struct pxe_device */
141
+			list_del ( &pxe->dev.siblings );
142
+		}
143
+	}
267 144
 
145
+	free ( pxe );
268 146
 	return 0;
269 147
 
270 148
  err:
@@ -299,7 +177,6 @@ static struct root_driver pxe_root_driver = {
299 177
 struct root_device pxe_root_device __root_device = {
300 178
 	.name = "PXE",
301 179
 	.driver = &pxe_root_driver,
302
-	.dev = {
303
-		.children = LIST_HEAD_INIT ( pxe_root_device.dev.children ),
304
-	},
305 180
 };
181
+
182
+#endif

Loading…
Cancel
Save