diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-02-02 22:41:00 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-02 22:41:00 -0800 |
commit | 702c7fbe7342403472e887508716add0c58c385c (patch) | |
tree | 639050b522cea25f4475d48da54380d61c7d10f3 /gpxe/src/arch/i386/interface/pxe/pxe_call.c | |
parent | 1e96e9cc1c3549c86dbf4e7caf880477e16e93e0 (diff) | |
download | syslinux.git-702c7fbe7342403472e887508716add0c58c385c.tar.gz syslinux.git-702c7fbe7342403472e887508716add0c58c385c.tar.xz syslinux.git-702c7fbe7342403472e887508716add0c58c385c.zip |
Update gPXE to version 1.0.0
Diffstat (limited to 'gpxe/src/arch/i386/interface/pxe/pxe_call.c')
-rw-r--r-- | gpxe/src/arch/i386/interface/pxe/pxe_call.c | 93 |
1 files changed, 73 insertions, 20 deletions
diff --git a/gpxe/src/arch/i386/interface/pxe/pxe_call.c b/gpxe/src/arch/i386/interface/pxe/pxe_call.c index 06dee25c..66a9b1e2 100644 --- a/gpxe/src/arch/i386/interface/pxe/pxe_call.c +++ b/gpxe/src/arch/i386/interface/pxe/pxe_call.c @@ -16,7 +16,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +FILE_LICENCE ( GPL2_OR_LATER ); + #include <gpxe/uaccess.h> +#include <gpxe/init.h> #include <registers.h> #include <biosint.h> #include <pxe.h> @@ -34,6 +37,9 @@ extern struct segoff __text16 ( pxe_int_1a_vector ); /** INT 1A handler */ extern void pxe_int_1a ( void ); +/** INT 1A hooked flag */ +static int int_1a_hooked = 0; + /** A function pointer to hold any PXE API call * * Used by pxe_api_call() to avoid large swathes of duplicated code. @@ -98,6 +104,7 @@ union pxenv_call { PXENV_EXIT_t ( * get_file_size ) ( struct s_PXENV_GET_FILE_SIZE * ); PXENV_EXIT_t ( * file_exec ) ( struct s_PXENV_FILE_EXEC * ); PXENV_EXIT_t ( * file_api_check ) ( struct s_PXENV_FILE_API_CHECK * ); + PXENV_EXIT_t ( * file_exit_hook ) ( struct s_PXENV_FILE_EXIT_HOOK * ); }; /** @@ -304,6 +311,10 @@ __asmcall void pxe_api_call ( struct i386_all_regs *ix86 ) { pxenv_call.file_api_check = pxenv_file_api_check; param_len = sizeof ( pxenv_any.file_api_check ); break; + case PXENV_FILE_EXIT_HOOK: + pxenv_call.file_exit_hook = pxenv_file_exit_hook; + param_len = sizeof ( pxenv_any.file_exit_hook ); + break; default: DBG ( "PXENV_UNKNOWN_%hx", opcode ); pxenv_call.unknown = pxenv_unknown; @@ -334,6 +345,18 @@ __asmcall void pxe_api_call ( struct i386_all_regs *ix86 ) { } /** + * Dispatch weak PXE API call with PXE stack available + * + * @v ix86 Registers for PXE call + * @ret present Zero (PXE stack present) + */ +int _pxe_api_call_weak ( struct i386_all_regs *ix86 ) +{ + pxe_api_call ( ix86 ); + return 0; +} + +/** * Dispatch PXE loader call * * @v es:di Address of PXE parameter block @@ -362,25 +385,6 @@ __asmcall void pxe_loader_call ( struct i386_all_regs *ix86 ) { } /** - * Hook INT 1A for PXE - * - */ -void pxe_hook_int1a ( void ) { - hook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a, - &pxe_int_1a_vector ); -} - -/** - * Unhook INT 1A for PXE - * - * @ret rc Return status code - */ -int pxe_unhook_int1a ( void ) { - return unhook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a, - &pxe_int_1a_vector ); -} - -/** * Calculate byte checksum as used by PXE * * @v data Data @@ -401,7 +405,7 @@ static uint8_t pxe_checksum ( void *data, size_t size ) { * Initialise !PXE and PXENV+ structures * */ -void pxe_init_structures ( void ) { +static void pxe_init_structures ( void ) { uint32_t rm_cs_phys = ( rm_cs << 4 ); uint32_t rm_ds_phys = ( rm_ds << 4 ); @@ -427,6 +431,55 @@ void pxe_init_structures ( void ) { pxenv.Checksum -= pxe_checksum ( &pxenv, sizeof ( pxenv ) ); } +/** PXE structure initialiser */ +struct init_fn pxe_init_fn __init_fn ( INIT_NORMAL ) = { + .initialise = pxe_init_structures, +}; + +/** + * Activate PXE stack + * + * @v netdev Net device to use as PXE net device + */ +void pxe_activate ( struct net_device *netdev ) { + + /* Ensure INT 1A is hooked */ + if ( ! int_1a_hooked ) { + hook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a, + &pxe_int_1a_vector ); + int_1a_hooked = 1; + } + + /* Set PXE network device */ + pxe_set_netdev ( netdev ); +} + +/** + * Deactivate PXE stack + * + * @ret rc Return status code + */ +int pxe_deactivate ( void ) { + int rc; + + /* Clear PXE network device */ + pxe_set_netdev ( NULL ); + + /* Ensure INT 1A is unhooked, if possible */ + if ( int_1a_hooked ) { + if ( ( rc = unhook_bios_interrupt ( 0x1a, + (unsigned int) pxe_int_1a, + &pxe_int_1a_vector ))!= 0){ + DBG ( "Could not unhook INT 1A: %s\n", + strerror ( rc ) ); + return rc; + } + int_1a_hooked = 0; + } + + return 0; +} + /** * Start PXE NBP at 0000:7c00 * |