[edk2] [PATCH v2 2/4] OvmfPkg: add apple boot support to Ovmf

Subject: [edk2] [PATCH v2 2/4] OvmfPkg: add apple boot support to Ovmf

From: reza.jelveh@tuhh.de

To: edk2-devel@lists.sourceforge.net

Date: 2014-08-22 15:34:17

From: Reza Jelveh 

Apple's boot.efi checks if the ConsoleControl protocol returns
EFI_SUCCESS in both GetMode and SetMode.

Apple uses a kernel extension to make parts of the DataHub protocol
available to the xnu kernel. The xnu kernel then checks for FSB
frequency and if it's not found fails with:

"tsc_init: EFI not supported!"
https://github.com/opensource-apple/xnu/blob/10.9/osfmk/i386/tsc.c

Lastly, some firmware settings are added to AppleSupport and written to
nvram.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Reza Jelveh 

--
The boot.efi for the ConsoleControl protocol can be found here:

http://reza.jelveh.me/assets/boot.efi
Signed-off-by: Reza Jelveh 
---
 OvmfPkg/Include/Library/AppleSupportLib.h          |  25 +++++
 OvmfPkg/Library/AppleSupportLib/AppleSupport.c     | 107 +++++++++++++++++++++
 .../Library/AppleSupportLib/AppleSupportLib.inf    |  48 +++++++++
 OvmfPkg/Library/AppleSupportLib/Common.h           |  24 +++++
 OvmfPkg/Library/AppleSupportLib/Console.c          |  86 +++++++++++++++++
 OvmfPkg/Library/AppleSupportLib/Console.h          |  28 ++++++
 OvmfPkg/Library/AppleSupportLib/Datahub.c          | 104 ++++++++++++++++++++
 OvmfPkg/Library/AppleSupportLib/Datahub.h          |  32 ++++++
 8 files changed, 454 insertions(+)
 create mode 100644 OvmfPkg/Include/Library/AppleSupportLib.h
 create mode 100644 OvmfPkg/Library/AppleSupportLib/AppleSupport.c
 create mode 100644 OvmfPkg/Library/AppleSupportLib/AppleSupportLib.inf
 create mode 100644 OvmfPkg/Library/AppleSupportLib/Common.h
 create mode 100644 OvmfPkg/Library/AppleSupportLib/Console.c
 create mode 100644 OvmfPkg/Library/AppleSupportLib/Console.h
 create mode 100644 OvmfPkg/Library/AppleSupportLib/Datahub.c
 create mode 100644 OvmfPkg/Library/AppleSupportLib/Datahub.h

diff --git a/OvmfPkg/Include/Library/AppleSupportLib.h b/OvmfPkg/Include/Library/AppleSupportLib.h
new file mode 100644
index 0000000..4d5db9b
--- /dev/null
+++ b/OvmfPkg/Include/Library/AppleSupportLib.h
@@ -0,0 +1,25 @@
+/** @file
+*
+*  Copyright (c) 2014, Reza Jelveh. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _APPLESUPPORT_LIB_INCLUDED_
+#define _APPLESUPPORT_LIB_INCLUDED_
+
+EFI_STATUS
+EFIAPI
+InitializeAppleSupport (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+#endif
diff --git a/OvmfPkg/Library/AppleSupportLib/AppleSupport.c b/OvmfPkg/Library/AppleSupportLib/AppleSupport.c
new file mode 100644
index 0000000..7eb6b00
--- /dev/null
+++ b/OvmfPkg/Library/AppleSupportLib/AppleSupport.c
@@ -0,0 +1,107 @@
+/** @file
+*
+*  Copyright (c) 2014, Reza Jelveh. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Console.h"
+#include "Datahub.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+
+EFI_GUID gAppleFirmwareVariableGuid = {
+    0x4D1EDE05, 0x38C7, 0x4A6A, {0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x8C, 0x14 }
+};
+
+/**
+  Register Handler for the specified interrupt source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+  @param Handler  Callback for interrupt. NULL to unregister
+
+  @retval  EFI_SUCCESS            The firmware has successfully stored the variable and its data as
+  defined by the Attributes.
+  @retval  EFI_INVALID_PARAMETER  An invalid combination of attribute bits was supplied, or the
+  DataSize exceeds the maximum allowed.
+  @retval  EFI_INVALID_PARAMETER  VariableName is an empty Unicode string.
+  @retval  EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
+  @retval  EFI_DEVICE_ERROR       The variable could not be saved due to a hardware failure.
+  @retval  EFI_WRITE_PROTECTED    The variable in question is read-only.
+  @retval  EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
+  @retval  EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
+  set but the AuthInfo does NOT pass the validation check carried
+  out by the firmware.
+
+**/
+EFI_STATUS
+InitializeFirmware ()
+{
+  EFI_STATUS          Status;
+
+  UINT32              BackgroundClear = 0x00000000;
+  UINT32              FwFeatures      = 0x80000015;
+  UINT32              FwFeaturesMask  = 0x800003ff;
+
+  Status = gRT->SetVariable(L"BackgroundClear",
+                            &gAppleFirmwareVariableGuid,
+                            EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                            sizeof(BackgroundClear), &BackgroundClear);
+
+  Status = gRT->SetVariable(L"FirmwareFeatures",
+                            &gAppleFirmwareVariableGuid,
+                            EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                            sizeof(FwFeatures), &FwFeatures);
+
+  Status = gRT->SetVariable(L"FirmwareFeaturesMask",
+                            &gAppleFirmwareVariableGuid,
+                            EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                            sizeof(FwFeaturesMask), &FwFeaturesMask);
+
+  return Status;
+}
+
+/**
+  Register driver.
+
+  @param  ImageHandle   of the loaded driver
+  @param  SystemTable   Pointer to the System Table
+
+  @retval EFI_SUCCESS   Driver registered
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeAppleSupport (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                         Status;
+
+  Status = InitializeConsoleControl(ImageHandle);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = InitializeDatahub(ImageHandle);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = InitializeFirmware();
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
diff --git a/OvmfPkg/Library/AppleSupportLib/AppleSupportLib.inf b/OvmfPkg/Library/AppleSupportLib/AppleSupportLib.inf
new file mode 100644
index 0000000..f450645
--- /dev/null
+++ b/OvmfPkg/Library/AppleSupportLib/AppleSupportLib.inf
@@ -0,0 +1,48 @@
+#/* @file
+#  Copyright (c) 2014, Reza Jelveh. All rights reserved.
+#  
+#  This program and the accompanying materials                          
+#  are licensed and made available under the terms and conditions of the BSD License         
+#  which accompanies this distribution.  The full text of the license may be found at        
+#  http://opensource.org/licenses/bsd-license.php                                            
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+#
+#*/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = AppleSupportLib
+  FILE_GUID                      = CEC880AF-68DF-4CDF-BBA5-FF9B202382AB
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = AppleSupportLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  AppleSupport.c
+  Console.c
+  Datahub.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  BaseLib
+  DebugLib
+  MemoryAllocationLib
+  BaseMemoryLib
+
+[Protocols]
+  gEfiConsoleControlProtocolGuid  
+  gEfiDataHubProtocolGuid
diff --git a/OvmfPkg/Library/AppleSupportLib/Common.h b/OvmfPkg/Library/AppleSupportLib/Common.h
new file mode 100644
index 0000000..0d78210
--- /dev/null
+++ b/OvmfPkg/Library/AppleSupportLib/Common.h
@@ -0,0 +1,24 @@
+/** @file
+*
+*  Copyright (c) 2014, Reza Jelveh. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+
+#ifndef _APPLESUPPORT_COMMON_H_INCLUDED_
+#define _APPLESUPPORT_COMMON_H_INCLUDED_
+
+#include 
+#include 
+#include 
+#include 
+
+#endif
diff --git a/OvmfPkg/Library/AppleSupportLib/Console.c b/OvmfPkg/Library/AppleSupportLib/Console.c
new file mode 100644
index 0000000..8485c46
--- /dev/null
+++ b/OvmfPkg/Library/AppleSupportLib/Console.c
@@ -0,0 +1,86 @@
+/** @file
+*
+*  Copyright (c) 2014, Reza Jelveh. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Console.h"
+
+EFI_STATUS EFIAPI
+GetModeImpl(
+    IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
+    OUT EFI_CONSOLE_CONTROL_SCREEN_MODE   *Mode,
+    OUT BOOLEAN                           *GopUgaExists,  OPTIONAL
+    OUT BOOLEAN                           *StdInLocked    OPTIONAL
+    )
+{
+  *Mode = EfiConsoleControlScreenGraphics;
+
+  if (GopUgaExists)
+    *GopUgaExists = TRUE;
+  if (StdInLocked)
+    *StdInLocked = FALSE;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS EFIAPI
+SetModeImpl(
+    IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
+    IN  EFI_CONSOLE_CONTROL_SCREEN_MODE   Mode
+    )
+{
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS EFIAPI
+LockStdInImpl(
+    IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
+    IN CHAR16                             *Password
+    )
+{
+  return EFI_SUCCESS;
+}
+
+
+
+EFI_CONSOLE_CONTROL_PROTOCOL gConsoleController =
+{
+  GetModeImpl,
+  SetModeImpl,
+};
+
+/**
+  Install ConsoleControl protocol, which is needed for Apple's
+  boot.efi
+
+  @param  ImageHandle   of the loaded driver
+
+  @retval EFI_SUCCESS       Successfully installed protocol handler
+  @retval EFI_DEVICE_ERROR  ConsoleProtocol could not be installed
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeConsoleControl (
+  IN EFI_HANDLE         ImageHandle
+  )
+{
+  EFI_STATUS                         Status;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+      &ImageHandle,
+      &gEfiConsoleControlProtocolGuid,
+      &gConsoleController,
+      NULL
+      );
+
+  return Status;
+}
diff --git a/OvmfPkg/Library/AppleSupportLib/Console.h b/OvmfPkg/Library/AppleSupportLib/Console.h
new file mode 100644
index 0000000..2453f33
--- /dev/null
+++ b/OvmfPkg/Library/AppleSupportLib/Console.h
@@ -0,0 +1,28 @@
+/** @file
+*
+*  Copyright (c) 2014, Reza Jelveh. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _APPLESUPPORT_CONSOLE_H_INCLUDED_
+#define _APPLESUPPORT_CONSOLE_H_INCLUDED_
+
+#include "Common.h"
+
+#include 
+
+EFI_STATUS
+EFIAPI
+InitializeConsoleControl (
+  IN EFI_HANDLE         ImageHandle
+  );
+
+#endif
diff --git a/OvmfPkg/Library/AppleSupportLib/Datahub.c b/OvmfPkg/Library/AppleSupportLib/Datahub.c
new file mode 100644
index 0000000..4d43ff0
--- /dev/null
+++ b/OvmfPkg/Library/AppleSupportLib/Datahub.c
@@ -0,0 +1,104 @@
+/** @file
+*
+*  Copyright (c) 2011, Reza Jelveh. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Datahub.h"
+
+EFI_GUID gAppleSystemInfoProducerNameGuid = {0x64517CC8, 0x6561, 0x4051, {0xB0, 0x3C, 0x59, 0x64, 0xB6, 0x0F, 0x4C, 0x7A}};
+EFI_GUID gAppleFsbFrequencyPropertyGuid = {0xD1A04D55, 0x75B9, 0x41A3, {0x90, 0x36, 0x8F, 0x4A, 0x26, 0x1C, 0xBB, 0xA2}};
+EFI_GUID gAppleDevicePathsSupportedGuid = {0x5BB91CF7, 0xD816, 0x404B, {0x86, 0x72, 0x68, 0xF2, 0x7F, 0x78, 0x31, 0xDC}};
+
+typedef struct {
+  UINT32              DataNameSize;
+  UINT32              DataSize;
+} EFI_PROPERTY_SUBCLASS_RECORD;
+
+typedef struct {
+  EFI_SUBCLASS_TYPE1_HEADER   Header;
+  EFI_PROPERTY_SUBCLASS_RECORD  Record;
+} EFI_PROPERTY_SUBCLASS_DATA;
+
+
+EFI_STATUS
+SetEfiPlatformProperty (
+    IN EFI_DATA_HUB_PROTOCOL *DataHub,
+    IN CONST EFI_STRING Name,
+    EFI_GUID EfiPropertyGuid,
+    VOID *Data,
+    UINT32 DataSize
+    )
+{
+  EFI_STATUS Status;
+  UINT32 DataNameSize;
+  EFI_PROPERTY_SUBCLASS_DATA *DataRecord;
+
+  DataNameSize = (UINT32)StrSize(Name);
+
+  DataRecord = AllocateZeroPool (sizeof (EFI_PROPERTY_SUBCLASS_DATA) + DataNameSize + DataSize);
+  ASSERT (DataRecord != NULL);
+
+  DataRecord->Header.Version = EFI_DATA_RECORD_HEADER_VERSION;
+  DataRecord->Header.HeaderSize = sizeof(EFI_SUBCLASS_TYPE1_HEADER);
+  DataRecord->Header.Instance = 0xFFFF;
+  DataRecord->Header.SubInstance = 0xFFFF;
+  DataRecord->Header.RecordType = 0xFFFFFFFF;
+  DataRecord->Record.DataNameSize = DataNameSize;
+  DataRecord->Record.DataSize = DataSize;
+
+
+  CopyMem((UINT8 *)DataRecord + sizeof(EFI_PROPERTY_SUBCLASS_DATA), Name, DataNameSize);
+  CopyMem((UINT8 *)DataRecord + sizeof(EFI_PROPERTY_SUBCLASS_DATA) + DataNameSize, Data, DataSize);
+
+  Status = DataHub->LogData(DataHub, &EfiPropertyGuid, &gAppleSystemInfoProducerNameGuid,
+                             EFI_DATA_RECORD_CLASS_DATA,
+                             DataRecord,
+                             sizeof(EFI_PROPERTY_SUBCLASS_DATA) + DataNameSize + DataSize);
+
+  if (DataRecord) {
+    gBS->FreePool(DataRecord);
+  }
+
+  return Status;
+}
+
+/**
+  Initialize the DataHub protocols data for the xnu kernel to
+  detect an EFI boot.
+
+  @param  ImageHandle   of the loaded driver
+
+  @retval EFI_SUCCESS Source was updated to support Handler.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeDatahub (
+  IN EFI_HANDLE         ImageHandle
+  )
+{
+  EFI_STATUS                         Status;
+  EFI_DATA_HUB_PROTOCOL              *DataHub;
+
+  Status = gBS->LocateProtocol(&gEfiDataHubProtocolGuid, NULL, (VOID **)&DataHub);
+  ASSERT_EFI_ERROR(Status);
+
+  UINT64 FsbFrequency = 667000000;
+  UINT32 DevicePathsSupported = 1;
+
+  SetEfiPlatformProperty(DataHub, L"FSBFrequency", gAppleFsbFrequencyPropertyGuid, &FsbFrequency, sizeof(UINT64));
+  SetEfiPlatformProperty(DataHub, L"DevicePathsSupported", gAppleDevicePathsSupportedGuid, &DevicePathsSupported, sizeof(UINT32));
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
diff --git a/OvmfPkg/Library/AppleSupportLib/Datahub.h b/OvmfPkg/Library/AppleSupportLib/Datahub.h
new file mode 100644
index 0000000..cf0853f
--- /dev/null
+++ b/OvmfPkg/Library/AppleSupportLib/Datahub.h
@@ -0,0 +1,32 @@
+/** @file
+*
+*  Copyright (c) 2014, Reza Jelveh. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _APPLESUPPORT_DATAHUB_H_INCLUDED_
+#define _APPLESUPPORT_DATAHUB_H_INCLUDED_
+
+#include "Common.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+EFI_STATUS
+EFIAPI
+InitializeDatahub (
+  IN EFI_HANDLE         ImageHandle
+  );
+
+#endif
-- 
1.9.2


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel