mirror of https://github.com/ipxe/ipxe.git
Add (untested) UNDI loader C-level implementation.
parent
7db6b4b79c
commit
dca470cb21
|
@ -298,6 +298,31 @@ void pxe_api_call ( struct i386_all_regs *ix86 ) {
|
||||||
ix86->regs.ax = ret;
|
ix86->regs.ax = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch PXE loader call
|
||||||
|
*
|
||||||
|
* @v es:di Address of PXE parameter block
|
||||||
|
* @ret ax PXE exit code
|
||||||
|
*/
|
||||||
|
void pxe_loader_call ( struct i386_all_regs *ix86 ) {
|
||||||
|
userptr_t uparams = real_to_user ( ix86->segs.es, ix86->regs.di );
|
||||||
|
struct s_UNDI_LOADER params;
|
||||||
|
PXENV_EXIT_t ret;
|
||||||
|
|
||||||
|
/* Copy parameter block from caller */
|
||||||
|
copy_from_user ( ¶ms, uparams, 0, sizeof ( params ) );
|
||||||
|
|
||||||
|
/* Set default status in case child routine fails to do so */
|
||||||
|
params.Status = PXENV_STATUS_FAILURE;
|
||||||
|
|
||||||
|
/* Call UNDI loader */
|
||||||
|
ret = undi_loader ( ¶ms );
|
||||||
|
|
||||||
|
/* Copy modified parameter block back to caller and return */
|
||||||
|
copy_to_user ( uparams, 0, ¶ms, sizeof ( params ) );
|
||||||
|
ix86->regs.ax = ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook INT 1A for PXE
|
* Hook INT 1A for PXE
|
||||||
*
|
*
|
||||||
|
|
|
@ -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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* 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.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#warning "Currently broken"
|
#include <gpxe/init.h>
|
||||||
#if 0
|
|
||||||
#include "pxe.h"
|
#include "pxe.h"
|
||||||
|
#include "pxe_call.h"
|
||||||
|
|
||||||
|
/** @file
|
||||||
|
*
|
||||||
|
* PXE UNDI loader
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
/* PXENV_UNDI_LOADER
|
/* PXENV_UNDI_LOADER
|
||||||
*
|
*
|
||||||
* Status: working
|
|
||||||
*
|
|
||||||
* 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 ) {
|
PXENV_EXIT_t undi_loader ( struct s_UNDI_LOADER *undi_loader ) {
|
||||||
uint32_t loader_phys = virt_to_phys ( undi_loader );
|
|
||||||
|
|
||||||
DBG ( "PXENV_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
|
/* Perform one-time initialisation (e.g. heap) */
|
||||||
* probably be a single initialise() function that does all
|
initialise();
|
||||||
* this, but it's currently split interestingly between main()
|
|
||||||
* and main_loop()...
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/* Set up PXE data structures */
|
||||||
|
pxe_init_structures();
|
||||||
|
|
||||||
/* CHECKME: Our init functions have probably already been
|
/* Fill in UNDI loader structure */
|
||||||
called by the ROM prefix's call to setup(), haven't
|
undi_loader->PXEptr.segment = rm_ds;
|
||||||
they? */
|
undi_loader->PXEptr.offset =
|
||||||
|
( ( unsigned ) & __from_text16 ( ppxe ) );
|
||||||
|
undi_loader->PXENVptr.segment = rm_ds;
|
||||||
|
undi_loader->PXENVptr.offset =
|
||||||
|
( ( unsigned ) & __from_text16 ( pxenv ) );
|
||||||
|
|
||||||
|
undi_loader->Status = PXENV_STATUS_SUCCESS;
|
||||||
|
|
||||||
/* We have relocated; the loader pointer is now invalid */
|
|
||||||
undi_loader = phys_to_virt ( loader_phys );
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* FIXME: can't use ENSURE_CAN_UNLOAD() thanks to newer gcc's
|
|
||||||
* barfing on unnamed struct/unions. */
|
|
||||||
/* ENSURE_CAN_UNLOAD ( undi_loader ); */
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
return PXENV_EXIT_SUCCESS;
|
return PXENV_EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
|
@ -45,6 +45,9 @@
|
||||||
*/
|
*/
|
||||||
static char *pxe_ris_filename = NULL;
|
static char *pxe_ris_filename = NULL;
|
||||||
|
|
||||||
|
/* Avoid dragging in isapnp.o unnecessarily */
|
||||||
|
uint16_t isapnp_read_port;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UNLOAD BASE CODE STACK
|
* UNLOAD BASE CODE STACK
|
||||||
*
|
*
|
||||||
|
@ -180,9 +183,6 @@ PXENV_EXIT_t pxenv_restart_tftp ( struct s_PXENV_TFTP_READ_FILE
|
||||||
* Status: working
|
* Status: working
|
||||||
*/
|
*/
|
||||||
PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi ) {
|
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 bus_type;
|
||||||
unsigned int location;
|
unsigned int location;
|
||||||
struct net_device *netdev;
|
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",
|
DBG ( "PXENV_START_UNDI %04x:%04x:%04x",
|
||||||
start_undi->AX, start_undi->BX, start_undi->DX );
|
start_undi->AX, start_undi->BX, start_undi->DX );
|
||||||
|
|
||||||
/* Probe for devices, etc. */
|
/* Determine bus type and location. Use a heuristic to decide
|
||||||
startup();
|
* whether we are PCI or ISAPnP
|
||||||
|
*/
|
||||||
/* Determine bus type and location */
|
if ( ( start_undi->DX >= ISAPNP_READ_PORT_MIN ) &&
|
||||||
isapnp_read_port = start_undi->DX;
|
( start_undi->DX <= ISAPNP_READ_PORT_MAX ) &&
|
||||||
isapnp_csn = start_undi->BX;
|
( start_undi->BX >= ISAPNP_CSN_MIN ) &&
|
||||||
pci_busdevfn = start_undi->AX;
|
( start_undi->BX <= ISAPNP_CSN_MAX ) ) {
|
||||||
|
|
||||||
/* 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 ) ) {
|
|
||||||
bus_type = BUS_TYPE_ISAPNP;
|
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 {
|
} else {
|
||||||
bus_type = BUS_TYPE_PCI;
|
bus_type = BUS_TYPE_PCI;
|
||||||
location = pci_busdevfn;
|
location = start_undi->AX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Probe for devices, etc. */
|
||||||
|
startup();
|
||||||
|
|
||||||
/* Look for a matching net device */
|
/* Look for a matching net device */
|
||||||
netdev = find_netdev_by_location ( bus_type, location );
|
netdev = find_netdev_by_location ( bus_type, location );
|
||||||
if ( ! netdev ) {
|
if ( ! netdev ) {
|
||||||
|
|
Loading…
Reference in New Issue