From a814eff38ea0e300b56a899138505abf5a8f9dff Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 11 Jul 2012 18:16:13 +0100 Subject: [PATCH] [pxe] Add PXENV_FILE_CMDLINE API call Allow a PXE NBP to obtain its command line (if any) via the new PXE API call PXENV_FILE_CMDLINE. Signed-off-by: Michael Brown --- src/arch/i386/image/pxe_image.c | 9 ++++++ src/arch/i386/include/pxe.h | 1 + src/arch/i386/include/pxe_api.h | 21 ++++++++++++++ src/arch/i386/interface/pxe/pxe_file.c | 38 ++++++++++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/src/arch/i386/image/pxe_image.c b/src/arch/i386/image/pxe_image.c index bdccc93d..e037c793 100644 --- a/src/arch/i386/image/pxe_image.c +++ b/src/arch/i386/image/pxe_image.c @@ -35,6 +35,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); FEATURE ( FEATURE_IMAGE, "PXE", DHCP_EB_FEATURE_PXE, 1 ); +/** PXE command line */ +const char *pxe_cmdline; + /** * Execute PXE image * @@ -66,9 +69,15 @@ static int pxe_exec ( struct image *image ) { /* Activate PXE */ pxe_activate ( netdev ); + /* Set PXE command line */ + pxe_cmdline = image->cmdline; + /* Start PXE NBP */ rc = pxe_start_nbp(); + /* Clear PXE command line */ + pxe_cmdline = NULL; + /* Deactivate PXE */ pxe_deactivate(); diff --git a/src/arch/i386/include/pxe.h b/src/arch/i386/include/pxe.h index a6bb65c0..0206f683 100644 --- a/src/arch/i386/include/pxe.h +++ b/src/arch/i386/include/pxe.h @@ -188,6 +188,7 @@ struct pcir_header { ( ( 'P' << 0 ) + ( 'C' << 8 ) + ( 'I' << 16 ) + ( 'R' << 24 ) ) extern struct net_device *pxe_netdev; +extern const char *pxe_cmdline; extern void pxe_set_netdev ( struct net_device *netdev ); extern PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE diff --git a/src/arch/i386/include/pxe_api.h b/src/arch/i386/include/pxe_api.h index d01c262d..fd179ddb 100644 --- a/src/arch/i386/include/pxe_api.h +++ b/src/arch/i386/include/pxe_api.h @@ -1690,6 +1690,27 @@ typedef struct s_PXENV_FILE_EXIT_HOOK PXENV_FILE_EXIT_HOOK_t; /** @} */ /* pxenv_file_exit_hook */ +/** @defgroup pxenv_file_cmdline PXENV_FILE_CMDLINE + * + * FILE CMDLINE + * + * @{ + */ + +/** PXE API function code for pxenv_file_cmdline() */ +#define PXENV_FILE_CMDLINE 0x00e8 + +/** Parameter block for pxenv_file_cmdline() */ +struct s_PXENV_FILE_CMDLINE { + PXENV_STATUS_t Status; /**< PXE status code */ + UINT16_t BufferSize; /**< Data buffer size */ + SEGOFF16_t Buffer; /**< Data buffer */ +} __attribute__ (( packed )); + +typedef struct s_PXENV_FILE_CMDLINE PXENV_FILE_CMDLINE_t; + +/** @} */ /* pxe_file_cmdline */ + /** @} */ /* pxe_file_api */ /** @defgroup pxe_loader_api PXE Loader API diff --git a/src/arch/i386/interface/pxe/pxe_file.c b/src/arch/i386/interface/pxe/pxe_file.c index 7daaf919..ffb27087 100644 --- a/src/arch/i386/interface/pxe/pxe_file.c +++ b/src/arch/i386/interface/pxe/pxe_file.c @@ -232,6 +232,42 @@ static PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) { return PXENV_EXIT_SUCCESS; } +/** + * FILE CMDLINE + * + * @v file_cmdline Pointer to a struct s_PXENV_FILE_CMDLINE + * @v s_PXENV_FILE_CMDLINE::Buffer Buffer to contain command line + * @v s_PXENV_FILE_CMDLINE::BufferSize Size of buffer + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully + * @ret s_PXENV_FILE_EXEC::Status PXE status code + * @ret s_PXENV_FILE_EXEC::BufferSize Length of command line (including NUL) + * + */ +static PXENV_EXIT_t +pxenv_file_cmdline ( struct s_PXENV_FILE_CMDLINE *file_cmdline ) { + userptr_t buffer; + size_t max_len; + size_t len; + + DBG ( "PXENV_FILE_CMDLINE to %04x:%04x+%04x \"%s\"\n", + file_cmdline->Buffer.segment, file_cmdline->Buffer.offset, + file_cmdline->BufferSize, pxe_cmdline ); + + buffer = real_to_user ( file_cmdline->Buffer.segment, + file_cmdline->Buffer.offset ); + len = file_cmdline->BufferSize; + max_len = ( pxe_cmdline ? + ( strlen ( pxe_cmdline ) + 1 /* NUL */ ) : 0 ); + if ( len > max_len ) + len = max_len; + copy_to_user ( buffer, 0, pxe_cmdline, len ); + file_cmdline->BufferSize = max_len; + + file_cmdline->Status = PXENV_STATUS_SUCCESS; + return PXENV_EXIT_SUCCESS; +} + /** * FILE API CHECK * @@ -298,6 +334,8 @@ struct pxe_api_call pxe_file_api[] __pxe_api_call = { struct s_PXENV_GET_FILE_SIZE ), PXE_API_CALL ( PXENV_FILE_EXEC, pxenv_file_exec, struct s_PXENV_FILE_EXEC ), + PXE_API_CALL ( PXENV_FILE_CMDLINE, pxenv_file_cmdline, + struct s_PXENV_FILE_CMDLINE ), PXE_API_CALL ( PXENV_FILE_API_CHECK, pxenv_file_api_check, struct s_PXENV_FILE_API_CHECK ), };