Ver código fonte

Partial implementation of UNDI loader caller.

tags/v0.9.3
Michael Brown 17 anos atrás
pai
commit
9780fef360

+ 89
- 4
src/arch/i386/drivers/bus/pxedrv.c Ver arquivo

21
 #include <string.h>
21
 #include <string.h>
22
 #include <pxe.h>
22
 #include <pxe.h>
23
 #include <realmode.h>
23
 #include <realmode.h>
24
+#include <bios.h>
24
 
25
 
25
 /** @file
26
 /** @file
26
  *
27
  *
62
 	}
63
 	}
63
 
64
 
64
 	/* Fill in PXE driver loader fields */
65
 	/* Fill in PXE driver loader fields */
65
-	pxedrv->loader.segment = pxedrv->rom_segment;
66
-	pxedrv->loader.offset = undiloader;
66
+	pxedrv->loader_entry.segment = pxedrv->rom_segment;
67
+	pxedrv->loader_entry.offset = undiloader;
67
 	pxedrv->code_size = undi_rom_id.CodeSize;
68
 	pxedrv->code_size = undi_rom_id.CodeSize;
68
 	pxedrv->data_size = undi_rom_id.DataSize;
69
 	pxedrv->data_size = undi_rom_id.DataSize;
69
 
70
 
70
 	DBGC ( pxedrv, "PXEDRV %p has UNDI loader at %04x:%04x "
71
 	DBGC ( pxedrv, "PXEDRV %p has UNDI loader at %04x:%04x "
71
-	       "(code %04x data %04x)\n", pxedrv, pxedrv->loader.segment,
72
-	       pxedrv->loader.offset, pxedrv->code_size, pxedrv->data_size );
72
+	       "(code %04x data %04x)\n", pxedrv,
73
+	       pxedrv->loader_entry.segment, pxedrv->loader_entry.offset,
74
+	       pxedrv->code_size, pxedrv->data_size );
73
 	return 0;
75
 	return 0;
74
 }
76
 }
75
 
77
 
221
 	      vendor_id, device_id, rombase );
223
 	      vendor_id, device_id, rombase );
222
 	return NULL;
224
 	return NULL;
223
 }
225
 }
226
+
227
+/** Parameter block for calling UNDI loader */
228
+static struct s_UNDI_LOADER __data16 ( undi_loader );
229
+#define undi_loader __use_data16 ( undi_loader )
230
+
231
+/** UNDI loader entry point */
232
+static SEGOFF16_t __data16 ( undi_loader_entry );
233
+#define undi_loader_entry __use_data16 ( undi_loader_entry )
234
+
235
+/**
236
+ * Call UNDI loader to create a pixie
237
+ *
238
+ * @v pxedrv		PXE driver
239
+ * @v pxe		PXE device to be created
240
+ * @v pci_busdevfn	PCI bus:dev.fn (PCI devices only), or 0
241
+ * @v isapnp_csn	ISAPnP Card Select Number, or -1U
242
+ * @v isapnp_read_port	ISAPnP read port, or -1U
243
+ * @ret rc		Return status code
244
+ */
245
+static int pxedrv_load ( struct pxe_driver *pxedrv, struct pxe_device *pxe,
246
+			 unsigned int pci_busdevfn, unsigned int isapnp_csn,
247
+			 unsigned int isapnp_read_port ) {
248
+	int discard;
249
+	uint16_t exit;
250
+	uint16_t fbms;
251
+	unsigned int fbms_seg;
252
+	int rc;
253
+
254
+	memset ( &undi_loader, 0, sizeof ( undi_loader ) );
255
+	undi_loader.AX = pci_busdevfn;
256
+	undi_loader.BX = isapnp_csn;
257
+	undi_loader.DX = isapnp_read_port;
258
+
259
+	/* Allocate base memory for PXE stack */
260
+	get_real ( fbms, BDA_SEG, BDA_FBMS );
261
+	fbms_seg = ( fbms << 6 );
262
+	fbms_seg -= ( ( pxedrv->data_size + 0x0f ) >> 4 );
263
+	undi_loader.UNDI_DS = fbms_seg;
264
+	fbms_seg -= ( ( pxedrv->code_size + 0x0f ) >> 4 );
265
+	undi_loader.UNDI_CS = fbms_seg;
266
+	DBGC ( pxedrv, "PXEDRV %p loading to CS %04x and DS %04x\n", pxedrv,
267
+	       undi_loader.UNDI_CS, undi_loader.UNDI_DS );
268
+
269
+	/* Call loader */
270
+	undi_loader_entry = pxedrv->loader_entry;
271
+	__asm__ __volatile__ ( REAL_CODE ( "pushw %%ds\n\t"
272
+					   "pushw %w0\n\t"
273
+					   "lcall *%c3\n\t"
274
+					   "addw $4, %%sp\n\t" )
275
+			       : "=a" ( exit ), "=r" ( discard )
276
+			       : "0" ( & __from_data16 ( undi_loader ) ),
277
+			         "p" ( & __from_data16 ( undi_loader_entry )));
278
+	if ( exit != PXENV_EXIT_SUCCESS ) {
279
+		rc = -undi_loader.Status;
280
+		if ( rc == 0 ) /* Paranoia */
281
+			rc = -EIO;
282
+		DBGC ( pxedrv, "PXEDRV %p loader failed: %s\n",
283
+		       strerror ( rc ) );
284
+		return rc;
285
+	}
286
+
287
+	/* Update free base memory counter */
288
+	fbms = ( fbms_seg >> 6 );
289
+	put_real ( fbms, BDA_SEG, BDA_FBMS );
290
+
291
+	/* Record location of pixie in PXE device structure */
292
+	pxe->pxenv = undi_loader.PXENVptr;
293
+	pxe->ppxe = undi_loader.PXEptr;
294
+	return 0;
295
+}
296
+
297
+/**
298
+ * Call UNDI loader to create a pixie
299
+ *
300
+ * @v pxedrv		PXE driver
301
+ * @v pxe		PXE device to be created
302
+ * @v pci_busdevfn	PCI bus:dev.fn
303
+ * @ret rc		Return status code
304
+ */
305
+int pxedrv_load_pci ( struct pxe_driver *pxedrv, struct pxe_device *pxe,
306
+		      unsigned int bus, unsigned int devfn ) {
307
+	return pxedrv_load ( pxedrv, pxe, ( ( bus << 8 ) | devfn ), -1U, -1U );
308
+}

+ 1
- 0
src/arch/i386/include/bios.h Ver arquivo

2
 #define BIOS_H
2
 #define BIOS_H
3
 
3
 
4
 #define BDA_SEG 0x0040
4
 #define BDA_SEG 0x0040
5
+#define BDA_FBMS 0x0013
5
 #define BDA_NUM_DRIVES 0x0075
6
 #define BDA_NUM_DRIVES 0x0075
6
 
7
 
7
 extern unsigned long currticks ( void );
8
 extern unsigned long currticks ( void );

+ 1
- 1
src/include/pxe.h Ver arquivo

155
 	/** ROM segment address */
155
 	/** ROM segment address */
156
 	unsigned int rom_segment;
156
 	unsigned int rom_segment;
157
 	/** UNDI loader entry point */
157
 	/** UNDI loader entry point */
158
-	SEGOFF16_t loader;
158
+	SEGOFF16_t loader_entry;
159
 	/** Code segment size */
159
 	/** Code segment size */
160
 	size_t code_size;
160
 	size_t code_size;
161
 	/** Data segment size */
161
 	/** Data segment size */

+ 16
- 50
src/include/pxe_api.h Ver arquivo

1562
  * @{
1562
  * @{
1563
  */
1563
  */
1564
 
1564
 
1565
-/** The UNDI ROM ID structure */
1566
-struct s_UNDI_ROM_ID {
1567
-	/** Signature
1568
-	 *
1569
-	 * Contains the bytes 'U', 'N', 'D', 'I'.
1570
-	 */
1571
-	UINT32_t Signature;
1572
-	UINT8_t StructLength;		/**< Length of this structure */
1573
-	/** Checksum
1574
-	 *
1575
-	 * The byte checksum of this structure (using the length in
1576
-	 * #StructLength) must be zero.
1577
-	 */
1578
-	UINT8_t StructCksum;
1579
-	/** Revision of this structure
1580
-	 *
1581
-	 * For PXE version 2.1, this field must be zero.
1582
-	 */
1583
-	UINT8_t StructRev;
1584
-	/** UNDI revision
1585
-	 *
1586
-	 * UNDI revision, least significant byte first.  For UNDI
1587
-	 * version 2.1.0, this field will contain { 0x00, 0x01, 0x02 }.
1588
-	 */
1589
-	UINT8_t UNDIRev[3];
1590
-	/** UNDI loader routine entry point
1591
-	 *
1592
-	 * This is the entry point for calling undi_loader().
1593
-	 */
1594
-	UINT16_t UNDILoader;
1595
-	/** Minimum required stack segment size */
1596
-	UINT16_t StackSize;
1597
-	/** Minimum required data segment size */
1598
-	UINT16_t DataSize;
1599
-	/** Minimum required code segment size */
1600
-	UINT16_t CodeSize;
1601
-} PACKED;
1602
-
1603
-typedef struct s_UNDI_ROM_ID UNDI_ROM_ID_t;
1604
-
1605
 /** Parameter block for undi_loader() */
1565
 /** Parameter block for undi_loader() */
1606
 struct s_UNDI_LOADER {
1566
 struct s_UNDI_LOADER {
1607
-	/** struct s_UNDI_LOADER starts with a struct s_PXENV_START_UNDI */
1608
-	union undi_loader_start_undi {
1609
-		PXENV_STATUS_t Status;		/**< PXE status code */
1610
-		/** Parameters to pass to pxenv_start_undi() */
1611
-		struct s_PXENV_START_UNDI start_undi;
1612
-	} u;
1567
+	/** PXE status code */
1568
+	PXENV_STATUS_t Status;
1569
+	/** %ax register as for PXENV_START_UNDI */
1570
+	UINT16_t AX;
1571
+	/** %bx register as for PXENV_START_UNDI */
1572
+	UINT16_t BX;
1573
+	/** %dx register as for PXENV_START_UNDI */
1574
+	UINT16_t DX;
1575
+	/** %di register as for PXENV_START_UNDI */
1576
+	OFF16_t DI;
1577
+	/** %es register as for PXENV_START_UNDI */
1578
+	SEGSEL_t ES;
1613
 	/** UNDI data segment
1579
 	/** UNDI data segment
1614
 	 *
1580
 	 *
1615
 	 * @note The PXE specification defines the type of this field
1581
 	 * @note The PXE specification defines the type of this field
1617
 	 * equivalent anyway; for other architectures #SEGSEL_t makes
1583
 	 * equivalent anyway; for other architectures #SEGSEL_t makes
1618
 	 * more sense.
1584
 	 * more sense.
1619
 	 */
1585
 	 */
1620
-	SEGSEL_t	undi_ds;
1586
+	SEGSEL_t UNDI_DS;
1621
 	/** UNDI code segment
1587
 	/** UNDI code segment
1622
 	 *
1588
 	 *
1623
 	 * @note The PXE specification defines the type of this field
1589
 	 * @note The PXE specification defines the type of this field
1625
 	 * equivalent anyway; for other architectures #SEGSEL_t makes
1591
 	 * equivalent anyway; for other architectures #SEGSEL_t makes
1626
 	 * more sense.
1592
 	 * more sense.
1627
 	 */
1593
 	 */
1628
-	SEGSEL_t	undi_cs;
1594
+	SEGSEL_t UNDI_CS;
1629
 	/** Address of the !PXE structure (a struct s_PXE) */
1595
 	/** Address of the !PXE structure (a struct s_PXE) */
1630
-	SEGOFF16_t	pxe_ptr;
1596
+	SEGOFF16_t PXEptr;
1631
 	/** Address of the PXENV+ structure (a struct s_PXENV) */
1597
 	/** Address of the PXENV+ structure (a struct s_PXENV) */
1632
-	SEGOFF16_t	pxenv_ptr;
1598
+	SEGOFF16_t PXENVptr;
1633
 } PACKED;
1599
 } PACKED;
1634
 
1600
 
1635
 typedef struct s_UNDI_LOADER UNDI_LOADER_t;
1601
 typedef struct s_UNDI_LOADER UNDI_LOADER_t;

Carregando…
Cancelar
Salvar