iPXE
efi_download.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010 VMware, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19FILE_LICENCE ( GPL2_OR_LATER );
20FILE_SECBOOT ( PERMITTED );
21
22#include <stdlib.h>
23#include <string.h>
24#include <errno.h>
25#include <ipxe/open.h>
26#include <ipxe/process.h>
27#include <ipxe/iobuf.h>
28#include <ipxe/xfer.h>
29#include <ipxe/efi/efi.h>
30#include <ipxe/efi/efi_snp.h>
32
33/** iPXE download protocol GUID */
36
37/** A single in-progress file */
39 /** Data transfer interface that provides downloaded data */
41
42 /** Current file position */
43 size_t pos;
44
45 /** Data callback */
47
48 /** Finish callback */
50
51 /** Callback context */
52 void *context;
53};
54
55/* xfer interface */
56
57/**
58 * Transfer finished or was aborted
59 *
60 * @v file Data transfer file
61 * @v rc Reason for close
62 */
63static void efi_download_close ( struct efi_download_file *file, int rc ) {
64
65 file->finish_callback ( file->context, EFIRC ( rc ) );
66
67 intf_shutdown ( &file->xfer, rc );
68
70}
71
72/**
73 * Process received data
74 *
75 * @v file Data transfer file
76 * @v iobuf I/O buffer
77 * @v meta Data transfer metadata
78 * @ret rc Return status code
79 */
81 struct io_buffer *iobuf,
82 struct xfer_metadata *meta ) {
83 EFI_STATUS efirc;
84 size_t len = iob_len ( iobuf );
85 int rc;
86
87 /* Calculate new buffer position */
88 if ( meta->flags & XFER_FL_ABS_OFFSET )
89 file->pos = 0;
90 file->pos += meta->offset;
91
92 /* Call out to the data handler */
93 if ( ( efirc = file->data_callback ( file->context, iobuf->data,
94 len, file->pos ) ) != 0 ) {
95 rc = -EEFI ( efirc );
96 goto err_callback;
97 }
98
99 /* Update current buffer position */
100 file->pos += len;
101
102 /* Success */
103 rc = 0;
104
105 err_callback:
106 free_iob ( iobuf );
107 return rc;
108}
109
110/** Data transfer interface operations */
115
116/** EFI download data transfer interface descriptor */
119
120/**
121 * Start downloading a file, and register callback functions to handle the
122 * download.
123 *
124 * @v This iPXE Download Protocol instance
125 * @v Url URL to download from
126 * @v DataCallback Callback that will be invoked when data arrives
127 * @v FinishCallback Callback that will be invoked when the download ends
128 * @v Context Context passed to the Data and Finish callbacks
129 * @v File Token that can be used to abort the download
130 * @ret Status EFI status code
131 */
132static EFI_STATUS EFIAPI
134 CHAR8 *Url,
135 IPXE_DOWNLOAD_DATA_CALLBACK DataCallback,
136 IPXE_DOWNLOAD_FINISH_CALLBACK FinishCallback,
137 VOID *Context,
138 IPXE_DOWNLOAD_FILE *File ) {
139 struct efi_download_file *file;
140 int rc;
141
143
144 file = malloc ( sizeof ( struct efi_download_file ) );
145 if ( file == NULL ) {
148 }
149
151 rc = xfer_open ( &file->xfer, LOCATION_URI_STRING, Url );
152 if ( rc ) {
153 free ( file );
155 return EFIRC ( rc );
156 }
157
158 file->pos = 0;
159 file->data_callback = DataCallback;
160 file->finish_callback = FinishCallback;
161 file->context = Context;
162 *File = file;
163 return EFI_SUCCESS;
164}
165
166/**
167 * Forcibly abort downloading a file that is currently in progress.
168 *
169 * It is not safe to call this function after the Finish callback has executed.
170 *
171 * @v This iPXE Download Protocol instance
172 * @v File Token obtained from Start
173 * @v Status Reason for aborting the download
174 * @ret Status EFI status code
175 */
176static EFI_STATUS EFIAPI
180 struct efi_download_file *file = File;
181
182 efi_download_close ( file, -EEFI ( Status ) );
183 return EFI_SUCCESS;
184}
185
186/**
187 * Poll for more data from iPXE. This function will invoke the registered
188 * callbacks if data is available or if downloads complete.
189 *
190 * @v This iPXE Download Protocol instance
191 * @ret Status EFI status code
192 */
193static EFI_STATUS EFIAPI
198
199/** Publicly exposed iPXE download protocol */
205
206/**
207 * Install iPXE download protocol
208 *
209 * @v handle EFI handle
210 * @ret rc Return status code
211 */
213 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
214 EFI_STATUS efirc;
215 int rc;
216
218 &handle,
221 NULL );
222 if ( efirc ) {
223 rc = -EEFI ( efirc );
224 DBG ( "Could not install download protocol: %s\n",
225 strerror ( rc ) );
226 return rc;
227 }
228
229 return 0;
230}
231
232/**
233 * Uninstall iPXE download protocol
234 *
235 * @v handle EFI handle
236 */
char CHAR8
1-byte Character
#define EFIAPI
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define VOID
Undeclared type.
Definition Base.h:272
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
GUID EFI_GUID
128-bit buffer containing a unique identifier value.
#define EFI_OUT_OF_RESOURCES
Enumeration of EFI_STATUS.
#define EFI_SUCCESS
Enumeration of EFI_STATUS.
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
ring len
Length.
Definition dwmac.h:226
static int efi_download_deliver_iob(struct efi_download_file *file, struct io_buffer *iobuf, struct xfer_metadata *meta)
Process received data.
static IPXE_DOWNLOAD_PROTOCOL ipxe_download_protocol_interface
Publicly exposed iPXE download protocol.
static EFI_STATUS EFIAPI efi_download_start(IPXE_DOWNLOAD_PROTOCOL *This __unused, CHAR8 *Url, IPXE_DOWNLOAD_DATA_CALLBACK DataCallback, IPXE_DOWNLOAD_FINISH_CALLBACK FinishCallback, VOID *Context, IPXE_DOWNLOAD_FILE *File)
Start downloading a file, and register callback functions to handle the download.
static void efi_download_close(struct efi_download_file *file, int rc)
Transfer finished or was aborted.
void efi_download_uninstall(EFI_HANDLE handle)
Uninstall iPXE download protocol.
static EFI_STATUS EFIAPI efi_download_abort(IPXE_DOWNLOAD_PROTOCOL *This __unused, IPXE_DOWNLOAD_FILE File, EFI_STATUS Status)
Forcibly abort downloading a file that is currently in progress.
static EFI_STATUS EFIAPI efi_download_poll(IPXE_DOWNLOAD_PROTOCOL *This __unused)
Poll for more data from iPXE.
static struct interface_operation efi_xfer_operations[]
Data transfer interface operations.
int efi_download_install(EFI_HANDLE handle)
Install iPXE download protocol.
static EFI_GUID ipxe_download_protocol_guid
iPXE download protocol GUID
static struct interface_descriptor efi_download_file_xfer_desc
EFI download data transfer interface descriptor.
iPXE Download Protocol
struct _IPXE_DOWNLOAD_PROTOCOL IPXE_DOWNLOAD_PROTOCOL
void(EFIAPI * IPXE_DOWNLOAD_FINISH_CALLBACK)(IN VOID *Context, IN EFI_STATUS Status)
Callback function that is invoked when the file is finished downloading, or when a connection unexpec...
EFI_STATUS(EFIAPI * IPXE_DOWNLOAD_DATA_CALLBACK)(IN VOID *Context, IN VOID *Buffer, IN UINTN BufferLength, IN UINTN FileOffset)
Callback function that is invoked when data arrives for a particular file.
VOID * IPXE_DOWNLOAD_FILE
Token to represent a currently downloading file.
#define IPXE_DOWNLOAD_PROTOCOL_GUID
iPXE EFI SNP interface
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition efi_snp.h:92
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition efi_snp.h:100
uint8_t meta
Metadata flags.
Definition ena.h:3
Error codes.
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
EFI API.
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition efi.h:167
#define EFI_HANDLE
Definition efi.h:53
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
EFI_SYSTEM_TABLE * efi_systab
uint16_t handle
Handle.
Definition smbios.h:5
String functions.
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
I/O buffers.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
int xfer_open(struct interface *intf, int type,...)
Open location.
Definition open.c:203
Data transfer interface opening.
@ LOCATION_URI_STRING
Location is a URI string.
Definition open.h:35
void step(void)
Single-step a single process.
Definition process.c:99
Processes.
PXENV_STATUS_t Status
PXE status code.
Definition pxe_api.h:0
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
EFI Boot Services Table.
Definition UefiSpec.h:1931
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition UefiSpec.h:2011
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition UefiSpec.h:2010
A single in-progress file.
IPXE_DOWNLOAD_FINISH_CALLBACK finish_callback
Finish callback.
IPXE_DOWNLOAD_DATA_CALLBACK data_callback
Data callback.
struct interface xfer
Data transfer interface that provides downloaded data.
void * context
Callback context.
size_t pos
Current file position.
An object interface descriptor.
Definition interface.h:56
An object interface operation.
Definition interface.h:18
An object interface.
Definition interface.h:125
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
Data transfer metadata.
Definition xfer.h:23
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
Data transfer interfaces.
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition xfer.h:48