]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
EFI: retrieve and expose Apple device properties
authorJan Beulich <jbeulich@suse.com>
Tue, 14 Mar 2017 17:21:09 +0000 (18:21 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 14 Mar 2017 17:21:09 +0000 (18:21 +0100)
Apple's EFI drivers supply device properties which are needed to
support Macs optimally. They contain vital information which cannot be
obtained any other way (e.g. Thunderbolt Device ROM). They're also used
to convey the current device state so that OS drivers can pick up where
EFI drivers left (e.g. GPU mode setting).

Reference: Linux commit 58c5475aba67706b31d9237808d5d3d54074e5ea (see
there for the full original commit message, only the initial part of
which is being reproduced above)

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/common/efi/boot.c
xen/common/efi/efi.h
xen/common/efi/runtime.c
xen/include/public/platform.h

index be11d05b09857319ee90b7c91400692044b874c4..daf0c80ef81d949e258badee9014ef5d0a0f039c 100644 (file)
@@ -38,6 +38,8 @@
   { 0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94} }
 #define SHIM_LOCK_PROTOCOL_GUID \
   { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
+#define APPLE_PROPERTIES_PROTOCOL_GUID \
+  { 0x91bd12fe, 0xf6c3, 0x44fb, { 0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0} }
 
 typedef EFI_STATUS
 (/* _not_ EFIAPI */ *EFI_SHIM_LOCK_VERIFY) (
@@ -48,6 +50,44 @@ typedef struct {
     EFI_SHIM_LOCK_VERIFY Verify;
 } EFI_SHIM_LOCK_PROTOCOL;
 
+struct _EFI_APPLE_PROPERTIES;
+
+typedef EFI_STATUS
+(EFIAPI *EFI_APPLE_PROPERTIES_GET) (
+    IN struct _EFI_APPLE_PROPERTIES *This,
+    IN const EFI_DEVICE_PATH *Device,
+    IN const CHAR16 *PropertyName,
+    OUT VOID *Buffer,
+    IN OUT UINT32 *BufferSize);
+
+typedef EFI_STATUS
+(EFIAPI *EFI_APPLE_PROPERTIES_SET) (
+    IN struct _EFI_APPLE_PROPERTIES *This,
+    IN const EFI_DEVICE_PATH *Device,
+    IN const CHAR16 *PropertyName,
+    IN const VOID *Value,
+    IN UINT32 ValueLen);
+
+typedef EFI_STATUS
+(EFIAPI *EFI_APPLE_PROPERTIES_DELETE) (
+    IN struct _EFI_APPLE_PROPERTIES *This,
+    IN const EFI_DEVICE_PATH *Device,
+    IN const CHAR16 *PropertyName);
+
+typedef EFI_STATUS
+(EFIAPI *EFI_APPLE_PROPERTIES_GETALL) (
+    IN struct _EFI_APPLE_PROPERTIES *This,
+    OUT VOID *Buffer,
+    IN OUT UINT32 *BufferSize);
+
+typedef struct _EFI_APPLE_PROPERTIES {
+    UINTN Version; /* 0x10000 */
+    EFI_APPLE_PROPERTIES_GET Get;
+    EFI_APPLE_PROPERTIES_SET Set;
+    EFI_APPLE_PROPERTIES_DELETE Delete;
+    EFI_APPLE_PROPERTIES_GETALL GetAll;
+} EFI_APPLE_PROPERTIES;
+
 union string {
     CHAR16 *w;
     char *s;
@@ -900,6 +940,46 @@ static void __init efi_variables(void)
     }
 }
 
+static void __init efi_get_apple_properties(void)
+{
+    static EFI_GUID __initdata props_guid = APPLE_PROPERTIES_PROTOCOL_GUID;
+    EFI_APPLE_PROPERTIES *props;
+    UINT32 size = 0;
+    VOID *data;
+    EFI_STATUS status;
+
+    if ( efi_bs->LocateProtocol(&props_guid, NULL,
+                                (void **)&props) != EFI_SUCCESS )
+        return;
+    if ( props->Version != 0x10000 )
+    {
+        PrintStr(L"Warning: Unsupported Apple device properties version: ");
+        DisplayUint(props->Version, 0);
+        PrintStr(newline);
+        return;
+    }
+
+    props->GetAll(props, NULL, &size);
+    if ( !size ||
+         efi_bs->AllocatePool(EfiRuntimeServicesData, size,
+                              &data) != EFI_SUCCESS )
+        return;
+
+    status = props->GetAll(props, data, &size);
+    if ( status == EFI_SUCCESS )
+    {
+        efi_apple_properties_addr = (UINTN)data;
+        efi_apple_properties_len = size;
+    }
+    else
+    {
+        efi_bs->FreePool(data);
+        PrintStr(L"Warning: Could not query Apple device properties: ");
+        DisplayUint(status, 0);
+        PrintStr(newline);
+    }
+}
+
 static void __init efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN gop_mode)
 {
     EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
@@ -1208,6 +1288,9 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     /* Get snapshot of variable store parameters. */
     efi_variables();
 
+    /* Collect Apple device properties, if any. */
+    efi_get_apple_properties();
+
     efi_arch_memory_setup();
 
     if ( gop )
index 9fe6ff16b09fed47abf77e93dac6d42060c159f1..6b9c56ead1a4bdedaf7d8a954bf0738dbe9ee2eb 100644 (file)
@@ -36,3 +36,6 @@ extern const struct efi_pci_rom *efi_pci_roms;
 
 extern UINT64 efi_boot_max_var_store_size, efi_boot_remain_var_store_size,
               efi_boot_max_var_size;
+
+extern UINT64 efi_apple_properties_addr;
+extern UINTN efi_apple_properties_len;
index 25323dededf0335a6f1349b70afd061a575b68f0..20bc5328e009f8199cd0ce8e4fef3a8f8390b34a 100644 (file)
@@ -56,6 +56,9 @@ UINT64 __read_mostly efi_boot_max_var_store_size;
 UINT64 __read_mostly efi_boot_remain_var_store_size;
 UINT64 __read_mostly efi_boot_max_var_size;
 
+UINT64 __read_mostly efi_apple_properties_addr;
+UINTN __read_mostly efi_apple_properties_len;
+
 /* Bit field representing available EFI features/properties. */
 unsigned int efi_flags;
 
@@ -271,6 +274,14 @@ int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
             }
         return -ESRCH;
     }
+
+    case XEN_FW_EFI_APPLE_PROPERTIES:
+        if ( !efi_apple_properties_len )
+            return -ENODATA;
+        info->apple_properties.address = efi_apple_properties_addr;
+        info->apple_properties.size = efi_apple_properties_len;
+        break;
+
     default:
         return -EINVAL;
     }
index 1e6a6cee395633f5ccaae0ff3dc6ac632ad6adb5..94dbc3feb48ba2325183b7a38d11521eee7444d0 100644 (file)
@@ -240,6 +240,7 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_efi_runtime_call_t);
 #define  XEN_FW_EFI_MEM_INFO       3
 #define  XEN_FW_EFI_RT_VERSION     4
 #define  XEN_FW_EFI_PCI_ROM        5
+#define  XEN_FW_EFI_APPLE_PROPERTIES 6
 #define XEN_FW_KBD_SHIFT_FLAGS    5
 struct xenpf_firmware_info {
     /* IN variables. */
@@ -299,6 +300,11 @@ struct xenpf_firmware_info {
                 uint64_t address;
                 xen_ulong_t size;
             } pci_rom;
+            struct {
+                /* OUT variables */
+                uint64_t address;
+                xen_ulong_t size;
+            } apple_properties;
         } efi_info; /* XEN_FW_EFI_INFO */
 
         /* Int16, Fn02: Get keyboard shift flags. */