aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2016-11-12 16:32:36 -0500
committerIngo Molnar <mingo@kernel.org>2016-11-13 02:23:16 -0500
commit58c5475aba67706b31d9237808d5d3d54074e5ea (patch)
tree812358c3b6af51c93ef855450aded9d65501ce89
parent3552fdf29f01e5a889e88202dc55b67aa6766620 (diff)
x86/efi: Retrieve and assign Apple device properties
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). There's an EFI driver dubbed "AAPL,PathProperties" which implements a per-device key/value store. Other EFI drivers populate it using a custom protocol. The macOS bootloader /System/Library/CoreServices/boot.efi retrieves the properties with the same protocol. The kernel extension AppleACPIPlatform.kext subsequently merges them into the I/O Kit registry (see ioreg(8)) where they can be queried by other kernel extensions and user space. This commit extends the efistub to retrieve the device properties before ExitBootServices is called. It assigns them to devices in an fs_initcall so that they can be queried with the API in <linux/property.h>. Note that the device properties will only be available if the kernel is booted with the efistub. Distros should adjust their installers to always use the efistub on Macs. grub with the "linux" directive will not work unless the functionality of this commit is duplicated in grub. (The "linuxefi" directive should work but is not included upstream as of this writing.) The custom protocol has GUID 91BD12FE-F6C3-44FB-A5B7-5122AB303AE0 and looks like this: typedef struct { unsigned long version; /* 0x10000 */ efi_status_t (*get) ( IN struct apple_properties_protocol *this, IN struct efi_dev_path *device, IN efi_char16_t *property_name, OUT void *buffer, IN OUT u32 *buffer_len); /* EFI_SUCCESS, EFI_NOT_FOUND, EFI_BUFFER_TOO_SMALL */ efi_status_t (*set) ( IN struct apple_properties_protocol *this, IN struct efi_dev_path *device, IN efi_char16_t *property_name, IN void *property_value, IN u32 property_value_len); /* allocates copies of property name and value */ /* EFI_SUCCESS, EFI_OUT_OF_RESOURCES */ efi_status_t (*del) ( IN struct apple_properties_protocol *this, IN struct efi_dev_path *device, IN efi_char16_t *property_name); /* EFI_SUCCESS, EFI_NOT_FOUND */ efi_status_t (*get_all) ( IN struct apple_properties_protocol *this, OUT void *buffer, IN OUT u32 *buffer_len); /* EFI_SUCCESS, EFI_BUFFER_TOO_SMALL */ } apple_properties_protocol; Thanks to Pedro Vilaça for this blog post which was helpful in reverse engineering Apple's EFI drivers and bootloader: https://reverse.put.as/2016/06/25/apple-efi-firmware-passwords-and-the-scbo-myth/ If someone at Apple is reading this, please note there's a memory leak in your implementation of the del() function as the property struct is freed but the name and value allocations are not. Neither the macOS bootloader nor Apple's EFI drivers check the protocol version, but we do to avoid breakage if it's ever changed. It's been the same since at least OS X 10.6 (2009). The get_all() function conveniently fills a buffer with all properties in marshalled form which can be passed to the kernel as a setup_data payload. The number of device properties is dynamic and can change between a first invocation of get_all() (to determine the buffer size) and a second invocation (to retrieve the actual buffer), hence the peculiar loop which does not finish until the buffer size settles. The macOS bootloader does the same. The setup_data payload is later on unmarshalled in an fs_initcall. The idea is that most buses instantiate devices in "subsys" initcall level and drivers are usually bound to these devices in "device" initcall level, so we assign the properties in-between, i.e. in "fs" initcall level. This assumes that devices to which properties pertain are instantiated from a "subsys" initcall or earlier. That should always be the case since on macOS, AppleACPIPlatformExpert::matchEFIDevicePath() only supports ACPI and PCI nodes and we've fully scanned those buses during "subsys" initcall level. The second assumption is that properties are only needed from a "device" initcall or later. Seems reasonable to me, but should this ever not work out, an alternative approach would be to store the property sets e.g. in a btree early during boot. Then whenever device_add() is called, an EFI Device Path would have to be constructed for the newly added device, and looked up in the btree. That way, the property set could be assigned to the device immediately on instantiation. And this would also work for devices instantiated in a deferred fashion. It seems like this approach would be more complicated and require more code. That doesn't seem justified without a specific use case. For comparison, the strategy on macOS is to assign properties to objects in the ACPI namespace (AppleACPIPlatformExpert::mergeEFIProperties()). That approach is definitely wrong as it fails for devices not present in the namespace: The NHI EFI driver supplies properties for attached Thunderbolt devices, yet on Macs with Thunderbolt 1 only one device level behind the host controller is described in the namespace. Consequently macOS cannot assign properties for chained devices. With Thunderbolt 2 they started to describe three device levels behind host controllers in the namespace but this grossly inflates the SSDT and still fails if the user daisy-chained more than three devices. We copy the property names and values from the setup_data payload to swappable virtual memory and afterwards make the payload available to the page allocator. This is just for the sake of good housekeeping, it wouldn't occupy a meaningful amount of physical memory (4444 bytes on my machine). Only the payload is freed, not the setup_data header since otherwise we'd break the list linkage and we cannot safely update the predecessor's ->next link because there's no locking for the list. The payload is currently not passed on to kexec'ed kernels, same for PCI ROMs retrieved by setup_efi_pci(). This can be added later if there is demand by amending setup_efi_state(). The payload can then no longer be made available to the page allocator of course. Tested-by: Lukas Wunner <lukas@wunner.de> [MacBookPro9,1] Tested-by: Pierre Moreau <pierre.morrow@free.fr> [MacBookPro11,3] Signed-off-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk> Cc: Andreas Noever <andreas.noever@gmail.com> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Pedro Vilaça <reverser@put.as> Cc: Peter Jones <pjones@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: grub-devel@gnu.org Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/20161112213237.8804-9-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--Documentation/kernel-parameters.txt5
-rw-r--r--arch/x86/boot/compressed/eboot.c65
-rw-r--r--arch/x86/include/uapi/asm/bootparam.h1
-rw-r--r--drivers/firmware/efi/Kconfig13
-rw-r--r--drivers/firmware/efi/Makefile1
-rw-r--r--drivers/firmware/efi/apple-properties.c248
-rw-r--r--include/linux/efi.h17
7 files changed, 350 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 37babf91f2cb..86a31dfc036e 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1062,6 +1062,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1062 1062
1063 dscc4.setup= [NET] 1063 dscc4.setup= [NET]
1064 1064
1065 dump_apple_properties [X86]
1066 Dump name and content of EFI device properties on
1067 x86 Macs. Useful for driver authors to determine
1068 what data is available or for reverse-engineering.
1069
1065 dyndbg[="val"] [KNL,DYNAMIC_DEBUG] 1070 dyndbg[="val"] [KNL,DYNAMIC_DEBUG]
1066 module.dyndbg[="val"] 1071 module.dyndbg[="val"]
1067 Enable debug messages at boot time. See 1072 Enable debug messages at boot time. See
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index cc69e37548db..ff01c8fc76f7 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -537,6 +537,69 @@ free_handle:
537 efi_call_early(free_pool, pci_handle); 537 efi_call_early(free_pool, pci_handle);
538} 538}
539 539
540static void retrieve_apple_device_properties(struct boot_params *boot_params)
541{
542 efi_guid_t guid = APPLE_PROPERTIES_PROTOCOL_GUID;
543 struct setup_data *data, *new;
544 efi_status_t status;
545 u32 size = 0;
546 void *p;
547
548 status = efi_call_early(locate_protocol, &guid, NULL, &p);
549 if (status != EFI_SUCCESS)
550 return;
551
552 if (efi_table_attr(apple_properties_protocol, version, p) != 0x10000) {
553 efi_printk(sys_table, "Unsupported properties proto version\n");
554 return;
555 }
556
557 efi_call_proto(apple_properties_protocol, get_all, p, NULL, &size);
558 if (!size)
559 return;
560
561 do {
562 status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
563 size + sizeof(struct setup_data), &new);
564 if (status != EFI_SUCCESS) {
565 efi_printk(sys_table,
566 "Failed to alloc mem for properties\n");
567 return;
568 }
569
570 status = efi_call_proto(apple_properties_protocol, get_all, p,
571 new->data, &size);
572
573 if (status == EFI_BUFFER_TOO_SMALL)
574 efi_call_early(free_pool, new);
575 } while (status == EFI_BUFFER_TOO_SMALL);
576
577 new->type = SETUP_APPLE_PROPERTIES;
578 new->len = size;
579 new->next = 0;
580
581 data = (struct setup_data *)(unsigned long)boot_params->hdr.setup_data;
582 if (!data)
583 boot_params->hdr.setup_data = (unsigned long)new;
584 else {
585 while (data->next)
586 data = (struct setup_data *)(unsigned long)data->next;
587 data->next = (unsigned long)new;
588 }
589}
590
591static void setup_quirks(struct boot_params *boot_params)
592{
593 efi_char16_t const apple[] = { 'A', 'p', 'p', 'l', 'e', 0 };
594 efi_char16_t *fw_vendor = (efi_char16_t *)(unsigned long)
595 efi_table_attr(efi_system_table, fw_vendor, sys_table);
596
597 if (!memcmp(fw_vendor, apple, sizeof(apple))) {
598 if (IS_ENABLED(CONFIG_APPLE_PROPERTIES))
599 retrieve_apple_device_properties(boot_params);
600 }
601}
602
540static efi_status_t 603static efi_status_t
541setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height) 604setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
542{ 605{
@@ -1098,6 +1161,8 @@ struct boot_params *efi_main(struct efi_config *c,
1098 1161
1099 setup_efi_pci(boot_params); 1162 setup_efi_pci(boot_params);
1100 1163
1164 setup_quirks(boot_params);
1165
1101 status = efi_call_early(allocate_pool, EFI_LOADER_DATA, 1166 status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
1102 sizeof(*gdt), (void **)&gdt); 1167 sizeof(*gdt), (void **)&gdt);
1103 if (status != EFI_SUCCESS) { 1168 if (status != EFI_SUCCESS) {
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index c18ce67495fa..b10bf319ed20 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -7,6 +7,7 @@
7#define SETUP_DTB 2 7#define SETUP_DTB 2
8#define SETUP_PCI 3 8#define SETUP_PCI 3
9#define SETUP_EFI 4 9#define SETUP_EFI 4
10#define SETUP_APPLE_PROPERTIES 5
10 11
11/* ram_size flags */ 12/* ram_size flags */
12#define RAMDISK_IMAGE_START_MASK 0x07FF 13#define RAMDISK_IMAGE_START_MASK 0x07FF
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 893fda48fcdd..2e78b0b96d74 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -129,6 +129,19 @@ config EFI_TEST
129 Say Y here to enable the runtime services support via /dev/efi_test. 129 Say Y here to enable the runtime services support via /dev/efi_test.
130 If unsure, say N. 130 If unsure, say N.
131 131
132config APPLE_PROPERTIES
133 bool "Apple Device Properties"
134 depends on EFI_STUB && X86
135 select EFI_DEV_PATH_PARSER
136 select UCS2_STRING
137 help
138 Retrieve properties from EFI on Apple Macs and assign them to
139 devices, allowing for improved support of Apple hardware.
140 Properties that would otherwise be missing include the
141 Thunderbolt Device ROM and GPU configuration data.
142
143 If unsure, say Y if you have a Mac. Otherwise N.
144
132endmenu 145endmenu
133 146
134config UEFI_CPER 147config UEFI_CPER
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 3e91ae31f9d1..ad67342313ed 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o
22obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o 22obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o
23obj-$(CONFIG_EFI_TEST) += test/ 23obj-$(CONFIG_EFI_TEST) += test/
24obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o 24obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o
25obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o
25 26
26arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o 27arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o
27obj-$(CONFIG_ARM) += $(arm-obj-y) 28obj-$(CONFIG_ARM) += $(arm-obj-y)
diff --git a/drivers/firmware/efi/apple-properties.c b/drivers/firmware/efi/apple-properties.c
new file mode 100644
index 000000000000..c473f4c5ca34
--- /dev/null
+++ b/drivers/firmware/efi/apple-properties.c
@@ -0,0 +1,248 @@
1/*
2 * apple-properties.c - EFI device properties on Macs
3 * Copyright (C) 2016 Lukas Wunner <lukas@wunner.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License (version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU 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, see <http://www.gnu.org/licenses/>.
16 */
17
18#define pr_fmt(fmt) "apple-properties: " fmt
19
20#include <linux/bootmem.h>
21#include <linux/dmi.h>
22#include <linux/efi.h>
23#include <linux/property.h>
24#include <linux/slab.h>
25#include <linux/ucs2_string.h>
26#include <asm/setup.h>
27
28static bool dump_properties __initdata;
29
30static int __init dump_properties_enable(char *arg)
31{
32 dump_properties = true;
33 return 0;
34}
35
36__setup("dump_apple_properties", dump_properties_enable);
37
38struct dev_header {
39 u32 len;
40 u32 prop_count;
41 struct efi_dev_path path[0];
42 /*
43 * followed by key/value pairs, each key and value preceded by u32 len,
44 * len includes itself, value may be empty (in which case its len is 4)
45 */
46};
47
48struct properties_header {
49 u32 len;
50 u32 version;
51 u32 dev_count;
52 struct dev_header dev_header[0];
53};
54
55static u8 one __initdata = 1;
56
57static void __init unmarshal_key_value_pairs(struct dev_header *dev_header,
58 struct device *dev, void *ptr,
59 struct property_entry entry[])
60{
61 int i;
62
63 for (i = 0; i < dev_header->prop_count; i++) {
64 int remaining = dev_header->len - (ptr - (void *)dev_header);
65 u32 key_len, val_len;
66 char *key;
67
68 if (sizeof(key_len) > remaining)
69 break;
70
71 key_len = *(typeof(key_len) *)ptr;
72 if (key_len + sizeof(val_len) > remaining ||
73 key_len < sizeof(key_len) + sizeof(efi_char16_t) ||
74 *(efi_char16_t *)(ptr + sizeof(key_len)) == 0) {
75 dev_err(dev, "invalid property name len at %#zx\n",
76 ptr - (void *)dev_header);
77 break;
78 }
79
80 val_len = *(typeof(val_len) *)(ptr + key_len);
81 if (key_len + val_len > remaining ||
82 val_len < sizeof(val_len)) {
83 dev_err(dev, "invalid property val len at %#zx\n",
84 ptr - (void *)dev_header + key_len);
85 break;
86 }
87
88 /* 4 bytes to accommodate UTF-8 code points + null byte */
89 key = kzalloc((key_len - sizeof(key_len)) * 4 + 1, GFP_KERNEL);
90 if (!key) {
91 dev_err(dev, "cannot allocate property name\n");
92 break;
93 }
94 ucs2_as_utf8(key, ptr + sizeof(key_len),
95 key_len - sizeof(key_len));
96
97 entry[i].name = key;
98 entry[i].is_array = true;
99 entry[i].length = val_len - sizeof(val_len);
100 entry[i].pointer.raw_data = ptr + key_len + sizeof(val_len);
101 if (!entry[i].length) {
102 /* driver core doesn't accept empty properties */
103 entry[i].length = 1;
104 entry[i].pointer.raw_data = &one;
105 }
106
107 if (dump_properties) {
108 dev_info(dev, "property: %s\n", entry[i].name);
109 print_hex_dump(KERN_INFO, pr_fmt(), DUMP_PREFIX_OFFSET,
110 16, 1, entry[i].pointer.raw_data,
111 entry[i].length, true);
112 }
113
114 ptr += key_len + val_len;
115 }
116
117 if (i != dev_header->prop_count) {
118 dev_err(dev, "got %d device properties, expected %u\n", i,
119 dev_header->prop_count);
120 print_hex_dump(KERN_ERR, pr_fmt(), DUMP_PREFIX_OFFSET,
121 16, 1, dev_header, dev_header->len, true);
122 return;
123 }
124
125 dev_info(dev, "assigning %d device properties\n", i);
126}
127
128static int __init unmarshal_devices(struct properties_header *properties)
129{
130 size_t offset = offsetof(struct properties_header, dev_header[0]);
131
132 while (offset + sizeof(struct dev_header) < properties->len) {
133 struct dev_header *dev_header = (void *)properties + offset;
134 struct property_entry *entry = NULL;
135 struct device *dev;
136 size_t len;
137 int ret, i;
138 void *ptr;
139
140 if (offset + dev_header->len > properties->len ||
141 dev_header->len <= sizeof(*dev_header)) {
142 pr_err("invalid len in dev_header at %#zx\n", offset);
143 return -EINVAL;
144 }
145
146 ptr = dev_header->path;
147 len = dev_header->len - sizeof(*dev_header);
148
149 dev = efi_get_device_by_path((struct efi_dev_path **)&ptr, &len);
150 if (IS_ERR(dev)) {
151 pr_err("device path parse error %ld at %#zx:\n",
152 PTR_ERR(dev), ptr - (void *)dev_header);
153 print_hex_dump(KERN_ERR, pr_fmt(), DUMP_PREFIX_OFFSET,
154 16, 1, dev_header, dev_header->len, true);
155 dev = NULL;
156 goto skip_device;
157 }
158
159 entry = kcalloc(dev_header->prop_count + 1, sizeof(*entry),
160 GFP_KERNEL);
161 if (!entry) {
162 dev_err(dev, "cannot allocate properties\n");
163 goto skip_device;
164 }
165
166 unmarshal_key_value_pairs(dev_header, dev, ptr, entry);
167 if (!entry[0].name)
168 goto skip_device;
169
170 ret = device_add_properties(dev, entry); /* makes deep copy */
171 if (ret)
172 dev_err(dev, "error %d assigning properties\n", ret);
173
174 for (i = 0; entry[i].name; i++)
175 kfree(entry[i].name);
176
177skip_device:
178 kfree(entry);
179 put_device(dev);
180 offset += dev_header->len;
181 }
182
183 return 0;
184}
185
186static int __init map_properties(void)
187{
188 struct properties_header *properties;
189 struct setup_data *data;
190 u32 data_len;
191 u64 pa_data;
192 int ret;
193
194 if (!dmi_match(DMI_SYS_VENDOR, "Apple Inc.") &&
195 !dmi_match(DMI_SYS_VENDOR, "Apple Computer, Inc."))
196 return 0;
197
198 pa_data = boot_params.hdr.setup_data;
199 while (pa_data) {
200 data = ioremap(pa_data, sizeof(*data));
201 if (!data) {
202 pr_err("cannot map setup_data header\n");
203 return -ENOMEM;
204 }
205
206 if (data->type != SETUP_APPLE_PROPERTIES) {
207 pa_data = data->next;
208 iounmap(data);
209 continue;
210 }
211
212 data_len = data->len;
213 iounmap(data);
214
215 data = ioremap(pa_data, sizeof(*data) + data_len);
216 if (!data) {
217 pr_err("cannot map setup_data payload\n");
218 return -ENOMEM;
219 }
220
221 properties = (struct properties_header *)data->data;
222 if (properties->version != 1) {
223 pr_err("unsupported version:\n");
224 print_hex_dump(KERN_ERR, pr_fmt(), DUMP_PREFIX_OFFSET,
225 16, 1, properties, data_len, true);
226 ret = -ENOTSUPP;
227 } else if (properties->len != data_len) {
228 pr_err("length mismatch, expected %u\n", data_len);
229 print_hex_dump(KERN_ERR, pr_fmt(), DUMP_PREFIX_OFFSET,
230 16, 1, properties, data_len, true);
231 ret = -EINVAL;
232 } else
233 ret = unmarshal_devices(properties);
234
235 /*
236 * Can only free the setup_data payload but not its header
237 * to avoid breaking the chain of ->next pointers.
238 */
239 data->len = 0;
240 iounmap(data);
241 free_bootmem_late(pa_data + sizeof(*data), data_len);
242
243 return ret;
244 }
245 return 0;
246}
247
248fs_initcall(map_properties);
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 261767212c47..a07a476178cd 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -443,6 +443,22 @@ typedef struct {
443#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000 443#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000
444#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 0x40000 444#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 0x40000
445 445
446typedef struct {
447 u32 version;
448 u32 get;
449 u32 set;
450 u32 del;
451 u32 get_all;
452} apple_properties_protocol_32_t;
453
454typedef struct {
455 u64 version;
456 u64 get;
457 u64 set;
458 u64 del;
459 u64 get_all;
460} apple_properties_protocol_64_t;
461
446/* 462/*
447 * Types and defines for EFI ResetSystem 463 * Types and defines for EFI ResetSystem
448 */ 464 */
@@ -592,6 +608,7 @@ void efi_native_runtime_setup(void);
592#define EFI_RNG_ALGORITHM_RAW EFI_GUID(0xe43176d7, 0xb6e8, 0x4827, 0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61) 608#define EFI_RNG_ALGORITHM_RAW EFI_GUID(0xe43176d7, 0xb6e8, 0x4827, 0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61)
593#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20) 609#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20)
594#define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) 610#define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
611#define APPLE_PROPERTIES_PROTOCOL_GUID EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb, 0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0)
595 612
596/* 613/*
597 * This GUID is used to pass to the kernel proper the struct screen_info 614 * This GUID is used to pass to the kernel proper the struct screen_info