aboutsummaryrefslogtreecommitdiffstats
path: root/src/interface
diff options
context:
space:
mode:
authorMichael Brown <mcb30@etherboot.org>2007-07-03 23:41:35 +0100
committerMichael Brown <mcb30@etherboot.org>2007-07-03 23:41:35 +0100
commitdca470cb21f75ec2c509af66b807307bf3b7c5ac (patch)
tree726278e3457a1f894152434f15b33a96e552dc17 /src/interface
parent7db6b4b79cff2a3c16390db74a0aa8bb1b134a7f (diff)
downloadipxe-dca470cb21f75ec2c509af66b807307bf3b7c5ac.tar.gz
Add (untested) UNDI loader C-level implementation.
Diffstat (limited to 'src/interface')
-rw-r--r--src/interface/pxe/pxe_loader.c78
-rw-r--r--src/interface/pxe/pxe_preboot.c35
2 files changed, 39 insertions, 74 deletions
diff --git a/src/interface/pxe/pxe_loader.c b/src/interface/pxe/pxe_loader.c
index d72838fd..1f2f8ca6 100644
--- a/src/interface/pxe/pxe_loader.c
+++ b/src/interface/pxe/pxe_loader.c
@@ -1,11 +1,5 @@
-/** @file
- *
- * PXE UNDI loader
- *
- */
-
/*
- * Copyright (C) 2004 Michael Brown <mbrown@fensystems.co.uk>.
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -22,65 +16,37 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#warning "Currently broken"
-#if 0
+#include <gpxe/init.h>
#include "pxe.h"
+#include "pxe_call.h"
-/* PXENV_UNDI_LOADER
+/** @file
+ *
+ * PXE UNDI loader
*
- * Status: working
+ */
+
+/* PXENV_UNDI_LOADER
*
- * NOTE: This is not a genuine PXE API call; the loader has a separate
- * entry point. However, to simplify the mapping of the PXE API to
- * the internal Etherboot API, both are directed through the same
- * interface.
*/
PXENV_EXIT_t undi_loader ( struct s_UNDI_LOADER *undi_loader ) {
- uint32_t loader_phys = virt_to_phys ( undi_loader );
-
- DBG ( "PXENV_UNDI_LOADER" );
-
- /* Set UNDI DS as our real-mode stack */
- use_undi_ds_for_rm_stack ( undi_loader->undi_ds );
-
- /* FIXME: These lines are borrowed from main.c. There should
- * probably be a single initialise() function that does all
- * this, but it's currently split interestingly between main()
- * and main_loop()...
- */
-
-
- /* CHECKME: Our init functions have probably already been
- called by the ROM prefix's call to setup(), haven't
- they? */
-
+ DBG ( "[PXENV_UNDI_LOADER]" );
- /* We have relocated; the loader pointer is now invalid */
- undi_loader = phys_to_virt ( loader_phys );
+ /* Perform one-time initialisation (e.g. heap) */
+ initialise();
- /* Install PXE stack to area specified by NBP */
- install_pxe_stack ( VIRTUAL ( undi_loader->undi_cs, 0 ) );
-
- /* Call pxenv_start_undi to set parameters. Why the hell PXE
- * requires these parameters to be provided twice is beyond
- * the wit of any sane man. Don't worry if it fails; the NBP
- * should call PXENV_START_UNDI separately anyway.
- */
- pxenv_start_undi ( &undi_loader->u.start_undi );
- /* Unhook stack; the loader is not meant to hook int 1a etc,
- * but the call the pxenv_start_undi will cause it to happen.
- */
+ /* Set up PXE data structures */
+ pxe_init_structures();
- /* FIXME: can't use ENSURE_CAN_UNLOAD() thanks to newer gcc's
- * barfing on unnamed struct/unions. */
- /* ENSURE_CAN_UNLOAD ( undi_loader ); */
+ /* Fill in UNDI loader structure */
+ undi_loader->PXEptr.segment = rm_ds;
+ undi_loader->PXEptr.offset =
+ ( ( unsigned ) & __from_text16 ( ppxe ) );
+ undi_loader->PXENVptr.segment = rm_ds;
+ undi_loader->PXENVptr.offset =
+ ( ( unsigned ) & __from_text16 ( pxenv ) );
- /* Fill in addresses of !PXE and PXENV+ structures */
- PTR_TO_SEGOFF16 ( &pxe_stack->pxe, undi_loader->pxe_ptr );
- PTR_TO_SEGOFF16 ( &pxe_stack->pxenv, undi_loader->pxenv_ptr );
-
- undi_loader->u.Status = PXENV_STATUS_SUCCESS;
+ undi_loader->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
}
-#endif
diff --git a/src/interface/pxe/pxe_preboot.c b/src/interface/pxe/pxe_preboot.c
index b2ae5372..b4e2206a 100644
--- a/src/interface/pxe/pxe_preboot.c
+++ b/src/interface/pxe/pxe_preboot.c
@@ -45,6 +45,9 @@
*/
static char *pxe_ris_filename = NULL;
+/* Avoid dragging in isapnp.o unnecessarily */
+uint16_t isapnp_read_port;
+
/**
* UNLOAD BASE CODE STACK
*
@@ -180,9 +183,6 @@ PXENV_EXIT_t pxenv_restart_tftp ( struct s_PXENV_TFTP_READ_FILE
* Status: working
*/
PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi ) {
- unsigned int isapnp_read_port;
- unsigned int isapnp_csn;
- unsigned int pci_busdevfn;
unsigned int bus_type;
unsigned int location;
struct net_device *netdev;
@@ -190,26 +190,25 @@ PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi ) {
DBG ( "PXENV_START_UNDI %04x:%04x:%04x",
start_undi->AX, start_undi->BX, start_undi->DX );
- /* Probe for devices, etc. */
- startup();
-
- /* Determine bus type and location */
- isapnp_read_port = start_undi->DX;
- isapnp_csn = start_undi->BX;
- pci_busdevfn = start_undi->AX;
-
- /* Use a heuristic to decide whether we are PCI or ISAPnP */
- if ( ( isapnp_read_port >= ISAPNP_READ_PORT_MIN ) &&
- ( isapnp_read_port <= ISAPNP_READ_PORT_MAX ) &&
- ( isapnp_csn >= ISAPNP_CSN_MIN ) &&
- ( isapnp_csn <= ISAPNP_CSN_MAX ) ) {
+ /* Determine bus type and location. Use a heuristic to decide
+ * whether we are PCI or ISAPnP
+ */
+ if ( ( start_undi->DX >= ISAPNP_READ_PORT_MIN ) &&
+ ( start_undi->DX <= ISAPNP_READ_PORT_MAX ) &&
+ ( start_undi->BX >= ISAPNP_CSN_MIN ) &&
+ ( start_undi->BX <= ISAPNP_CSN_MAX ) ) {
bus_type = BUS_TYPE_ISAPNP;
- location = isapnp_csn;
+ location = start_undi->BX;
+ /* Record ISAPnP read port for use by isapnp.c */
+ isapnp_read_port = start_undi->DX;
} else {
bus_type = BUS_TYPE_PCI;
- location = pci_busdevfn;
+ location = start_undi->AX;
}
+ /* Probe for devices, etc. */
+ startup();
+
/* Look for a matching net device */
netdev = find_netdev_by_location ( bus_type, location );
if ( ! netdev ) {