From d38ba84d44c8110b604fba5df5d83b13ac5202f7 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Tue, 11 Feb 2020 14:28:59 -0600 Subject: [PATCH] efi: Add quirks for some unicorn Apple EFI protocols * grub and linux do the same thing. * Based on MIT code here: https://github.com/0xbb/apple_set_os.efi/blob/master/apple_set_os.c Change-Id: I299b3721197c5cdd4406d313d8769d4923f7edb4 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2239 Reviewed-by: Adrien Destugues --- .../platform/efi/protocol/apple-setos.h | 17 ++++++ src/system/boot/platform/efi/Jamfile | 1 + src/system/boot/platform/efi/quirks.cpp | 59 +++++++++++++++++++ src/system/boot/platform/efi/quirks.h | 18 ++++++ src/system/boot/platform/efi/start.cpp | 4 ++ 5 files changed, 99 insertions(+) create mode 100644 headers/private/kernel/platform/efi/protocol/apple-setos.h create mode 100644 src/system/boot/platform/efi/quirks.cpp create mode 100644 src/system/boot/platform/efi/quirks.h diff --git a/headers/private/kernel/platform/efi/protocol/apple-setos.h b/headers/private/kernel/platform/efi/protocol/apple-setos.h new file mode 100644 index 0000000000..d14d163ea4 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/apple-setos.h @@ -0,0 +1,17 @@ +// Copyright 2015 Bruno Bierbaumer +// Released under the terms of the MIT License + +#pragma once + +#include + +#define EFI_APPLE_SET_OS_GUID \ + {0xc5c5da95, 0x7d5c, 0x45e6, {0xb2, 0xf1, 0x3f, 0xd5, 0x2b, 0xb1, 0x00, 0x77}} +extern efi_guid AppleSetOSProtocol; + +typedef struct efi_apple_set_os_protocol { + uint64_t Revision; + + efi_status (*SetOSVersion) (char* version) EFIAPI; + efi_status (*SetOSVendor) (char* vendor) EFIAPI; +} efi_apple_set_os_protocol; diff --git a/src/system/boot/platform/efi/Jamfile b/src/system/boot/platform/efi/Jamfile index 1675833a42..18a8ceafb9 100644 --- a/src/system/boot/platform/efi/Jamfile +++ b/src/system/boot/platform/efi/Jamfile @@ -26,6 +26,7 @@ local platform_src = menu.cpp devices.cpp cpu.cpp + quirks.cpp smp.cpp serial.cpp smp_trampoline.S diff --git a/src/system/boot/platform/efi/quirks.cpp b/src/system/boot/platform/efi/quirks.cpp new file mode 100644 index 0000000000..f585665dae --- /dev/null +++ b/src/system/boot/platform/efi/quirks.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2015, Bruno Bierbaumer. All rights reserved. + * Copyright 2019-2020, Haiku, Inc. All rights reserved. + * Released under the terms of the MIT License + */ + + +#include +#include + +#include "efi_platform.h" + + +#define APPLE_FAKE_OS_VENDOR "Apple Inc." +#define APPLE_FAKE_OS_VERSION "Mac OS X 10.9" + + +// Apple Hardware configures hardware differently depending on +// the operating system being booted. Examples include disabling +// and powering down the internal GPU on some device models. +static void +quirks_fake_apple(void) +{ + efi_guid appleSetOSProtocolGUID = EFI_APPLE_SET_OS_GUID; + efi_apple_set_os_protocol* set_os = NULL; + + efi_status status = kSystemTable->BootServices->LocateProtocol( + &appleSetOSProtocolGUID, NULL, (void**)&set_os); + + // If not relevant, we will exit here (the protocol doesn't exist) + if (status != EFI_SUCCESS || set_os == NULL) { + return; + } + + dprintf("Located Apple set_os protocol, applying EFI Apple Quirks...\n"); + + if (set_os->Revision != 0) { + status = set_os->SetOSVersion((char*)APPLE_FAKE_OS_VERSION); + if (status != EFI_SUCCESS) { + dprintf("%s: unable to set os version!\n", __func__); + return; + } + } + + status = set_os->SetOSVendor((char*)APPLE_FAKE_OS_VENDOR); + if (status != EFI_SUCCESS) { + dprintf("%s: unable to set os version!\n", __func__); + return; + } + + return; +} + + +void +quirks_init(void) +{ + quirks_fake_apple(); +} diff --git a/src/system/boot/platform/efi/quirks.h b/src/system/boot/platform/efi/quirks.h new file mode 100644 index 0000000000..66f110eddb --- /dev/null +++ b/src/system/boot/platform/efi/quirks.h @@ -0,0 +1,18 @@ +/* + * Copyright 2019-2020, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck IV + */ +#ifndef _QUIRKS_H +#define _QUIRKS_H + + +#include + + +void quirks_init(); + + +#endif /* _QUIRKS_H */ diff --git a/src/system/boot/platform/efi/start.cpp b/src/system/boot/platform/efi/start.cpp index dc48a55fff..9c3bf436a5 100644 --- a/src/system/boot/platform/efi/start.cpp +++ b/src/system/boot/platform/efi/start.cpp @@ -25,6 +25,7 @@ #include "console.h" #include "efi_platform.h" #include "mmu.h" +#include "quirks.h" #include "serial.h" #include "smp.h" #include "timer.h" @@ -150,6 +151,9 @@ platform_start_kernel(void) + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; dprintf("Kernel stack at %#lx\n", gKernelArgs.cpu_kstack[0].start); + // Apply any weird EFI quirks + quirks_init(); + // Prepare to exit EFI boot services. // Read the memory map. // First call is to determine the buffer size.