diff --git a/src/arch/i386/interface/pxe/pxe_call.c b/src/arch/i386/interface/pxe/pxe_call.c index b9c21ce5..5b307d40 100644 --- a/src/arch/i386/interface/pxe/pxe_call.c +++ b/src/arch/i386/interface/pxe/pxe_call.c @@ -97,6 +97,7 @@ union pxenv_call { PXENV_EXIT_t ( * file_read ) ( struct s_PXENV_FILE_READ * ); 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 * ); }; /** @@ -299,6 +300,10 @@ __cdecl void pxe_api_call ( struct i386_all_regs *ix86 ) { pxenv_call.file_exec = pxenv_file_exec; param_len = sizeof ( pxenv_any.file_exec ); break; + case PXENV_FILE_API_CHECK: + pxenv_call.file_api_check = pxenv_file_api_check; + param_len = sizeof ( pxenv_any.file_api_check ); + break; default: DBG ( "PXENV_UNKNOWN_%hx", opcode ); pxenv_call.unknown = pxenv_unknown; diff --git a/src/include/pxe.h b/src/include/pxe.h index 8b3ca14c..6d332ac7 100644 --- a/src/include/pxe.h +++ b/src/include/pxe.h @@ -64,6 +64,7 @@ union u_PXENV_ANY { struct s_PXENV_FILE_READ file_read; struct s_PXENV_GET_FILE_SIZE get_file_size; struct s_PXENV_FILE_EXEC file_exec; + struct s_PXENV_FILE_API_CHECK file_api_check; }; typedef union u_PXENV_ANY PXENV_ANY_t; diff --git a/src/include/pxe_api.h b/src/include/pxe_api.h index 53708ed4..b3d4bca8 100644 --- a/src/include/pxe_api.h +++ b/src/include/pxe_api.h @@ -1706,6 +1706,32 @@ extern PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ); /** @} */ /* pxenv_file_exec */ +/** @defgroup pxenv_file_api_check PXENV_FILE_API_CHECK + * + * FILE API CHECK + * + * @{ + */ + +/** PXE API function code for pxenv_file_api_check() */ +#define PXENV_FILE_API_CHECK 0x00e6 + +/** Parameter block for pxenv_file_api_check() */ +struct s_PXENV_FILE_API_CHECK { + PXENV_STATUS_t Status; /**< PXE status code */ + UINT16_t Size; /**< Size of structure */ + UINT32_t Magic; /**< Magic number */ + UINT32_t Provider; /**< Implementation identifier */ + UINT32_t APIMask; /**< Supported API functions */ + UINT32_t Flags; /**< Reserved for the future */ +} PACKED; + +typedef struct s_PXENV_FILE_API_CHECK PXENV_FILE_API_CHECK_t; + +extern PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check ); + +/** @} */ /* pxenv_file_api_check */ + /** @} */ /* pxe_file_api */ /** @defgroup pxe_loader_api PXE Loader API diff --git a/src/interface/pxe/pxe_file.c b/src/interface/pxe/pxe_file.c index 718f5e38..41674588 100644 --- a/src/interface/pxe/pxe_file.c +++ b/src/interface/pxe/pxe_file.c @@ -227,3 +227,38 @@ PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) { file_exec->Status = PXENV_STATUS_SUCCESS; return PXENV_EXIT_SUCCESS; } + +/** + * FILE API CHECK + * + * @v file_exec Pointer to a struct s_PXENV_FILE_API_CHECK + * @v s_PXENV_FILE_API_CHECK::Magic Inbound magic number (0x91d447b2) + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully + * @ret s_PXENV_FILE_API_CHECK::Status PXE status code + * @ret s_PXENV_FILE_API_CHECK::Magic Outbound magic number (0xe9c17b20) + * @ret s_PXENV_FILE_API_CHECK::Provider "gPXE" (0x45585067) + * @ret s_PXENV_FILE_API_CHECK::APIMask API function bitmask + * @ret s_PXENV_FILE_API_CHECK::Flags Reserved + * + */ +PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check ) { + DBG ( "PXENV_FILE_API_CHECK" ); + + if ( file_api_check->Magic != 0x91d447b2 ) { + file_api_check->Status = PXENV_STATUS_BAD_FUNC; + return PXENV_EXIT_FAILURE; + } else if ( file_api_check->Size < + sizeof(struct s_PXENV_FILE_API_CHECK) ) { + file_api_check->Status = PXENV_STATUS_OUT_OF_RESOURCES; + return PXENV_EXIT_FAILURE; + } else { + file_api_check->Status = PXENV_STATUS_SUCCESS; + file_api_check->Size = sizeof(struct s_PXENV_FILE_API_CHECK); + file_api_check->Magic = 0xe9c17b20; + file_api_check->Provider = 0x45585067; /* "gPXE" */ + file_api_check->APIMask = 0x0000007f; /* Functions e0-e6 */ + file_api_check->Flags = 0; /* None defined */ + return PXENV_EXIT_SUCCESS; + } +}