summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/arch/i386/image/pxe_image.c32
-rw-r--r--src/arch/i386/include/pxe_call.h15
-rw-r--r--src/arch/i386/interface/pxe/pxe_call.c66
-rw-r--r--src/arch/i386/interface/pxe/pxe_entry.S10
4 files changed, 64 insertions, 59 deletions
diff --git a/src/arch/i386/image/pxe_image.c b/src/arch/i386/image/pxe_image.c
index f88c45970..27a7e42d2 100644
--- a/src/arch/i386/image/pxe_image.c
+++ b/src/arch/i386/image/pxe_image.c
@@ -23,10 +23,12 @@
*
*/
+#include <pxe.h>
+#include <pxe_call.h>
#include <gpxe/uaccess.h>
#include <gpxe/image.h>
#include <gpxe/segment.h>
-#include <pxe_call.h>
+#include <gpxe/netdevice.h>
/** PXE load address segment */
#define PXE_LOAD_SEGMENT 0
@@ -43,7 +45,33 @@ struct image_type pxe_image_type __image_type ( PROBE_PXE );
* @ret rc Return status code
*/
static int pxe_exec ( struct image *image __unused ) {
- return pxe_boot();
+ struct net_device *netdev;
+ int discard_b, discard_c;
+ uint16_t rc;
+
+ /* Ensure that PXE stack is ready to use */
+ pxe_init_structures();
+ pxe_hook_int1a();
+
+ /* Arbitrarily pick the first open network device to use for PXE */
+ for_each_netdev ( netdev ) {
+ pxe_netdev = netdev;
+ break;
+ }
+
+ /* Far call to PXE NBP */
+ __asm__ __volatile__ ( REAL_CODE ( "pushw %%cx\n\t"
+ "pushw %%ax\n\t"
+ "movw %%cx, %%es\n\t"
+ "lcall $0, $0x7c00\n\t" )
+ : "=a" ( rc ), "=b" ( discard_b ),
+ "=c" ( discard_c )
+ : "a" ( & __from_text16 ( ppxe ) ),
+ "b" ( & __from_text16 ( pxenv ) ),
+ "c" ( rm_cs )
+ : "edx", "esi", "edi", "ebp", "memory" );
+
+ return rc;
}
/**
diff --git a/src/arch/i386/include/pxe_call.h b/src/arch/i386/include/pxe_call.h
index 84893b550..c6c1c6d89 100644
--- a/src/arch/i386/include/pxe_call.h
+++ b/src/arch/i386/include/pxe_call.h
@@ -6,6 +6,19 @@
* PXE API entry point
*/
-extern int pxe_boot ( void );
+#include <pxe_api.h>
+#include <realmode.h>
+
+/** !PXE structure */
+extern struct s_PXE __text16 ( ppxe );
+#define ppxe __use_text16 ( ppxe )
+
+/** PXENV+ structure */
+extern struct s_PXENV __text16 ( pxenv );
+#define pxenv __use_text16 ( pxenv )
+
+extern void pxe_hook_int1a ( void );
+extern int pxe_unhook_int1a ( void );
+extern void pxe_init_structures ( void );
#endif /* _PXE_CALL_H */
diff --git a/src/arch/i386/interface/pxe/pxe_call.c b/src/arch/i386/interface/pxe/pxe_call.c
index d39c65aac..7a1851555 100644
--- a/src/arch/i386/interface/pxe/pxe_call.c
+++ b/src/arch/i386/interface/pxe/pxe_call.c
@@ -34,14 +34,6 @@ extern struct segoff __text16 ( pxe_int_1a_vector );
/** INT 1A handler */
extern void pxe_int_1a ( void );
-/** !PXE structure */
-extern struct s_PXE __text16 ( pxe );
-#define pxe __use_text16 ( pxe )
-
-/** PXENV+ structure */
-extern struct s_PXENV __text16 ( pxenv );
-#define pxenv __use_text16 ( pxenv )
-
/** A function pointer to hold any PXE API call
*
* Used by pxe_api_call() to avoid large swathes of duplicated code.
@@ -310,7 +302,7 @@ void pxe_api_call ( struct i386_all_regs *ix86 ) {
* Hook INT 1A for PXE
*
*/
-void pxe_hook_int ( void ) {
+void pxe_hook_int1a ( void ) {
hook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a,
&pxe_int_1a_vector );
}
@@ -320,7 +312,7 @@ void pxe_hook_int ( void ) {
*
* @ret rc Return status code
*/
-int pxe_unhook_int ( void ) {
+int pxe_unhook_int1a ( void ) {
return unhook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a,
&pxe_int_1a_vector );
}
@@ -343,24 +335,24 @@ static uint8_t pxe_checksum ( void *data, size_t size ) {
}
/**
- * Initialise PXE stack
+ * Initialise !PXE and PXENV+ structures
*
*/
-void init_pxe ( void ) {
+void pxe_init_structures ( void ) {
uint32_t rm_cs_phys = ( rm_cs << 4 );
uint32_t rm_ds_phys = ( rm_ds << 4 );
/* Fill in missing segment fields */
- pxe.EntryPointSP.segment = rm_cs;
- pxe.EntryPointESP.segment = rm_cs;
- pxe.Stack.segment_address = rm_ds;
- pxe.Stack.Physical_address = rm_ds_phys;
- pxe.UNDIData.segment_address = rm_ds;
- pxe.UNDIData.Physical_address = rm_ds_phys;
- pxe.UNDICode.segment_address = rm_cs;
- pxe.UNDICode.Physical_address = rm_cs_phys;
- pxe.UNDICodeWrite.segment_address = rm_cs;
- pxe.UNDICodeWrite.Physical_address = rm_cs_phys;
+ ppxe.EntryPointSP.segment = rm_cs;
+ ppxe.EntryPointESP.segment = rm_cs;
+ ppxe.Stack.segment_address = rm_ds;
+ ppxe.Stack.Physical_address = rm_ds_phys;
+ ppxe.UNDIData.segment_address = rm_ds;
+ ppxe.UNDIData.Physical_address = rm_ds_phys;
+ ppxe.UNDICode.segment_address = rm_cs;
+ ppxe.UNDICode.Physical_address = rm_cs_phys;
+ ppxe.UNDICodeWrite.segment_address = rm_cs;
+ ppxe.UNDICodeWrite.Physical_address = rm_cs_phys;
pxenv.RMEntry.segment = rm_cs;
pxenv.StackSeg = rm_ds;
pxenv.UNDIDataSeg = rm_ds;
@@ -368,34 +360,6 @@ void init_pxe ( void ) {
pxenv.PXEPtr.segment = rm_cs;
/* Update checksums */
- pxe.StructCksum -= pxe_checksum ( &pxe, sizeof ( pxe ) );
+ ppxe.StructCksum -= pxe_checksum ( &ppxe, sizeof ( ppxe ) );
pxenv.Checksum -= pxe_checksum ( &pxenv, sizeof ( pxenv ) );
}
-
-/**
- * Boot via PXE NBP
- *
- * @ret rc Return status code
- */
-int pxe_boot ( void ) {
- int discard_b, discard_c;
- uint16_t rc;
-
- /* Ensure that PXE stack is ready to use */
- init_pxe();
- pxe_hook_int();
-
- /* Far call to PXE NBP */
- __asm__ __volatile__ ( REAL_CODE ( "pushw %%cx\n\t"
- "pushw %%ax\n\t"
- "movw %%cx, %%es\n\t"
- "lcall $0, $0x7c00\n\t" )
- : "=a" ( rc ), "=b" ( discard_b ),
- "=c" ( discard_c )
- : "a" ( & __from_text16 ( pxe ) ),
- "b" ( & __from_text16 ( pxenv ) ),
- "c" ( rm_cs )
- : "edx", "esi", "edi", "ebp", "memory" );
-
- return rc;
-}
diff --git a/src/arch/i386/interface/pxe/pxe_entry.S b/src/arch/i386/interface/pxe/pxe_entry.S
index 065fe7556..204894ef8 100644
--- a/src/arch/i386/interface/pxe/pxe_entry.S
+++ b/src/arch/i386/interface/pxe/pxe_entry.S
@@ -27,9 +27,9 @@
****************************************************************************
*/
.section ".text16.data"
- .globl pxe
+ .globl ppxe
.align 16
-pxe:
+ppxe:
.ascii "!PXE" /* Signature */
.byte pxe_length /* StructLength */
.byte 0 /* StructCksum */
@@ -52,8 +52,8 @@ pxe_segments:
.word 0, 0, 0, 0 /* BC_Code */
.word 0, 0, 0, 0 /* BC_CodeWrite */
.equ SegDescCnt, ( ( . - pxe_segments ) / 8 )
- .equ pxe_length, . - pxe
- .size pxe, . - pxe
+ .equ pxe_length, . - ppxe
+ .size ppxe, . - ppxe
/****************************************************************************
* PXENV+ structure
@@ -80,7 +80,7 @@ pxenv:
.word _data16_size /* UNDIDataSize */
.word 0 /* UNDICodeSeg */
.word _text16_size /* UNDICodeSize */
- .word pxe, 0 /* PXEPtr */
+ .word ppxe, 0 /* PXEPtr */
.equ pxenv_length, . - pxenv
.size pxenv, . - pxenv