summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2016-05-29 14:04:26 +0200
committerMichael Brown2016-05-29 14:10:14 +0200
commitaa4b038c70ca3e23c3126fda4318e9bbe77f3ea2 (patch)
treeb36ef7fe452af987a423785c729cf25c9ca42ce7 /src
parent[dhcp] Fix definitions for x86_64 and EFI BC client architectures (diff)
downloadipxe-aa4b038c70ca3e23c3126fda4318e9bbe77f3ea2.tar.gz
ipxe-aa4b038c70ca3e23c3126fda4318e9bbe77f3ea2.tar.xz
ipxe-aa4b038c70ca3e23c3126fda4318e9bbe77f3ea2.zip
[efi] Expose DHCP packets via the Apple NetBoot protocol
Mac OS X uses non-standard EFI protocols to obtain the DHCP packets from the UEFI firmware. Originally-implemented-by: Michael Kuron <m.kuron@gmx.de> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r--src/include/ipxe/efi/Protocol/AppleNetBoot.h46
-rw-r--r--src/include/ipxe/efi/efi.h1
-rw-r--r--src/interface/efi/efi_debug.c2
-rw-r--r--src/interface/efi/efi_guid.c5
-rw-r--r--src/interface/efi/efi_pxe.c94
5 files changed, 145 insertions, 3 deletions
diff --git a/src/include/ipxe/efi/Protocol/AppleNetBoot.h b/src/include/ipxe/efi/Protocol/AppleNetBoot.h
new file mode 100644
index 00000000..144beff1
--- /dev/null
+++ b/src/include/ipxe/efi/Protocol/AppleNetBoot.h
@@ -0,0 +1,46 @@
+#ifndef __EFI_APPLE_NET_BOOT_PROTOCOL_H__
+#define __EFI_APPLE_NET_BOOT_PROTOCOL_H__
+
+/** @file
+ *
+ * Apple Net Boot Protocol
+ *
+ */
+
+FILE_LICENCE ( BSD3 );
+
+#define EFI_APPLE_NET_BOOT_PROTOCOL_GUID \
+ { 0x78ee99fb, 0x6a5e, 0x4186, \
+ { 0x97, 0xde, 0xcd, 0x0a, 0xba, 0x34, 0x5a, 0x74 } }
+
+typedef struct _EFI_APPLE_NET_BOOT_PROTOCOL EFI_APPLE_NET_BOOT_PROTOCOL;
+
+/**
+ Get a DHCP packet obtained by the firmware during NetBoot.
+
+ @param This A pointer to the APPLE_NET_BOOT_PROTOCOL instance.
+ @param BufferSize A pointer to the size of the buffer in bytes.
+ @param DataBuffer The memory buffer to copy the packet to. If it is
+ NULL, then the size of the packet is returned
+ in BufferSize.
+ @retval EFI_SUCCESS The packet was copied.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the
+ current packet. BufferSize has been
+ updated with the size needed to
+ complete the request.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *GET_DHCP_RESPONSE) (
+ IN EFI_APPLE_NET_BOOT_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *DataBuffer
+ );
+
+struct _EFI_APPLE_NET_BOOT_PROTOCOL
+{
+ GET_DHCP_RESPONSE GetDhcpResponse;
+ GET_DHCP_RESPONSE GetBsdpResponse;
+};
+
+#endif /*__EFI_APPLE_NET_BOOT_PROTOCOL_H__ */
diff --git a/src/include/ipxe/efi/efi.h b/src/include/ipxe/efi/efi.h
index 390d4e6e..db9943a4 100644
--- a/src/include/ipxe/efi/efi.h
+++ b/src/include/ipxe/efi/efi.h
@@ -154,6 +154,7 @@ struct efi_config_table {
#define EEFI( efirc ) EPLATFORM ( EINFO_EPLATFORM, efirc )
extern EFI_GUID efi_absolute_pointer_protocol_guid;
+extern EFI_GUID efi_apple_net_boot_protocol_guid;
extern EFI_GUID efi_arp_protocol_guid;
extern EFI_GUID efi_arp_service_binding_protocol_guid;
extern EFI_GUID efi_block_io_protocol_guid;
diff --git a/src/interface/efi/efi_debug.c b/src/interface/efi/efi_debug.c
index 84160d64..19531fdc 100644
--- a/src/interface/efi/efi_debug.c
+++ b/src/interface/efi/efi_debug.c
@@ -71,6 +71,8 @@ struct efi_well_known_guid {
static struct efi_well_known_guid efi_well_known_guids[] = {
{ &efi_absolute_pointer_protocol_guid,
"AbsolutePointer" },
+ { &efi_apple_net_boot_protocol_guid,
+ "AppleNetBoot" },
{ &efi_arp_protocol_guid,
"Arp" },
{ &efi_arp_service_binding_protocol_guid,
diff --git a/src/interface/efi/efi_guid.c b/src/interface/efi/efi_guid.c
index 39da5efe..62ee5a51 100644
--- a/src/interface/efi/efi_guid.c
+++ b/src/interface/efi/efi_guid.c
@@ -25,6 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/AbsolutePointer.h>
+#include <ipxe/efi/Protocol/AppleNetBoot.h>
#include <ipxe/efi/Protocol/Arp.h>
#include <ipxe/efi/Protocol/BlockIo.h>
#include <ipxe/efi/Protocol/BusSpecificDriverOverride.h>
@@ -84,6 +85,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
EFI_GUID efi_absolute_pointer_protocol_guid
= EFI_ABSOLUTE_POINTER_PROTOCOL_GUID;
+/** Apple NetBoot protocol GUID */
+EFI_GUID efi_apple_net_boot_protocol_guid
+ = EFI_APPLE_NET_BOOT_PROTOCOL_GUID;
+
/** ARP protocol GUID */
EFI_GUID efi_arp_protocol_guid
= EFI_ARP_PROTOCOL_GUID;
diff --git a/src/interface/efi/efi_pxe.c b/src/interface/efi/efi_pxe.c
index 1847e3fd..a1f81df5 100644
--- a/src/interface/efi/efi_pxe.c
+++ b/src/interface/efi/efi_pxe.c
@@ -42,6 +42,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi_snp.h>
#include <ipxe/efi/efi_pxe.h>
#include <ipxe/efi/Protocol/PxeBaseCode.h>
+#include <ipxe/efi/Protocol/AppleNetBoot.h>
#include <usr/ifmgmt.h>
#include <config/general.h>
@@ -80,6 +81,8 @@ struct efi_pxe {
EFI_PXE_BASE_CODE_PROTOCOL base;
/** PXE base code mode */
EFI_PXE_BASE_CODE_MODE mode;
+ /** Apple NetBoot protocol */
+ EFI_APPLE_NET_BOOT_PROTOCOL apple;
/** TCP/IP network-layer protocol */
struct tcpip_net_protocol *tcpip;
@@ -1498,6 +1501,83 @@ static EFI_PXE_BASE_CODE_PROTOCOL efi_pxe_base_code_protocol = {
.SetPackets = efi_pxe_set_packets,
};
+/******************************************************************************
+ *
+ * Apple NetBoot protocol
+ *
+ ******************************************************************************
+ */
+
+/**
+ * Get DHCP/BSDP response
+ *
+ * @v packet Packet
+ * @v len Length of data buffer
+ * @v data Data buffer
+ * @ret efirc EFI status code
+ */
+static EFI_STATUS EFIAPI
+efi_apple_get_response ( EFI_PXE_BASE_CODE_PACKET *packet, UINTN *len,
+ VOID *data ) {
+
+ /* Check length */
+ if ( *len < sizeof ( *packet ) ) {
+ *len = sizeof ( *packet );
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ /* Copy packet */
+ memcpy ( data, packet, sizeof ( *packet ) );
+ *len = sizeof ( *packet );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * Get DHCP response
+ *
+ * @v apple Apple NetBoot protocol
+ * @v len Length of data buffer
+ * @v data Data buffer
+ * @ret efirc EFI status code
+ */
+static EFI_STATUS EFIAPI
+efi_apple_get_dhcp_response ( EFI_APPLE_NET_BOOT_PROTOCOL *apple,
+ UINTN *len, VOID *data ) {
+ struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
+
+ return efi_apple_get_response ( &pxe->mode.DhcpAck, len, data );
+}
+
+/**
+ * Get BSDP response
+ *
+ * @v apple Apple NetBoot protocol
+ * @v len Length of data buffer
+ * @v data Data buffer
+ * @ret efirc EFI status code
+ */
+static EFI_STATUS EFIAPI
+efi_apple_get_bsdp_response ( EFI_APPLE_NET_BOOT_PROTOCOL *apple,
+ UINTN *len, VOID *data ) {
+ struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
+
+ return efi_apple_get_response ( &pxe->mode.PxeReply, len, data );
+}
+
+/** Apple NetBoot protocol */
+static EFI_APPLE_NET_BOOT_PROTOCOL efi_apple_net_boot_protocol = {
+ .GetDhcpResponse = efi_apple_get_dhcp_response,
+ .GetBsdpResponse = efi_apple_get_bsdp_response,
+};
+
+/******************************************************************************
+ *
+ * Installer
+ *
+ ******************************************************************************
+ */
+
/**
* Install PXE base code protocol
*
@@ -1526,6 +1606,8 @@ int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev ) {
pxe->handle = handle;
memcpy ( &pxe->base, &efi_pxe_base_code_protocol, sizeof ( pxe->base ));
pxe->base.Mode = &pxe->mode;
+ memcpy ( &pxe->apple, &efi_apple_net_boot_protocol,
+ sizeof ( pxe->apple ) );
pxe->buf.op = &efi_pxe_buf_operations;
intf_init ( &pxe->tftp, &efi_pxe_tftp_desc, &pxe->refcnt );
intf_init ( &pxe->udp, &efi_pxe_udp_desc, &pxe->refcnt );
@@ -1545,7 +1627,9 @@ int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev ) {
/* Install PXE base code protocol */
if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
- &handle, &efi_pxe_base_code_protocol_guid, &pxe->base,
+ &handle,
+ &efi_pxe_base_code_protocol_guid, &pxe->base,
+ &efi_apple_net_boot_protocol_guid, &pxe->apple,
NULL ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( pxe, "PXE %s could not install base code protocol: %s\n",
@@ -1560,7 +1644,9 @@ int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev ) {
return 0;
bs->UninstallMultipleProtocolInterfaces (
- handle, &efi_pxe_base_code_protocol_guid, &pxe->base,
+ handle,
+ &efi_pxe_base_code_protocol_guid, &pxe->base,
+ &efi_apple_net_boot_protocol_guid, &pxe->apple,
NULL );
err_install_protocol:
ref_put ( &pxe->refcnt );
@@ -1590,7 +1676,9 @@ void efi_pxe_uninstall ( EFI_HANDLE handle ) {
/* Uninstall PXE base code protocol */
bs->UninstallMultipleProtocolInterfaces (
- handle, &efi_pxe_base_code_protocol_guid, &pxe->base,
+ handle,
+ &efi_pxe_base_code_protocol_guid, &pxe->base,
+ &efi_apple_net_boot_protocol_guid, &pxe->apple,
NULL );
/* Remove from list and drop list's reference */