xref: /openbmc/linux/drivers/firmware/efi/efi.c (revision a59511d1)
1 /*
2  * efi.c - EFI subsystem
3  *
4  * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
5  * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
6  * Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
7  *
8  * This code registers /sys/firmware/efi{,/efivars} when EFI is supported,
9  * allowing the efivarfs to be mounted or the efivars module to be loaded.
10  * The existance of /sys/firmware/efi may also be used by userspace to
11  * determine that the system supports EFI.
12  *
13  * This file is released under the GPLv2.
14  */
15 
16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 
18 #include <linux/kobject.h>
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/device.h>
22 #include <linux/efi.h>
23 #include <linux/of.h>
24 #include <linux/of_fdt.h>
25 #include <linux/io.h>
26 #include <linux/platform_device.h>
27 
28 #include <asm/early_ioremap.h>
29 
30 struct efi __read_mostly efi = {
31 	.mps			= EFI_INVALID_TABLE_ADDR,
32 	.acpi			= EFI_INVALID_TABLE_ADDR,
33 	.acpi20			= EFI_INVALID_TABLE_ADDR,
34 	.smbios			= EFI_INVALID_TABLE_ADDR,
35 	.smbios3		= EFI_INVALID_TABLE_ADDR,
36 	.sal_systab		= EFI_INVALID_TABLE_ADDR,
37 	.boot_info		= EFI_INVALID_TABLE_ADDR,
38 	.hcdp			= EFI_INVALID_TABLE_ADDR,
39 	.uga			= EFI_INVALID_TABLE_ADDR,
40 	.uv_systab		= EFI_INVALID_TABLE_ADDR,
41 	.fw_vendor		= EFI_INVALID_TABLE_ADDR,
42 	.runtime		= EFI_INVALID_TABLE_ADDR,
43 	.config_table		= EFI_INVALID_TABLE_ADDR,
44 	.esrt			= EFI_INVALID_TABLE_ADDR,
45 	.properties_table	= EFI_INVALID_TABLE_ADDR,
46 };
47 EXPORT_SYMBOL(efi);
48 
49 static bool disable_runtime;
50 static int __init setup_noefi(char *arg)
51 {
52 	disable_runtime = true;
53 	return 0;
54 }
55 early_param("noefi", setup_noefi);
56 
57 bool efi_runtime_disabled(void)
58 {
59 	return disable_runtime;
60 }
61 
62 static int __init parse_efi_cmdline(char *str)
63 {
64 	if (!str) {
65 		pr_warn("need at least one option\n");
66 		return -EINVAL;
67 	}
68 
69 	if (parse_option_str(str, "debug"))
70 		set_bit(EFI_DBG, &efi.flags);
71 
72 	if (parse_option_str(str, "noruntime"))
73 		disable_runtime = true;
74 
75 	return 0;
76 }
77 early_param("efi", parse_efi_cmdline);
78 
79 struct kobject *efi_kobj;
80 
81 /*
82  * Let's not leave out systab information that snuck into
83  * the efivars driver
84  */
85 static ssize_t systab_show(struct kobject *kobj,
86 			   struct kobj_attribute *attr, char *buf)
87 {
88 	char *str = buf;
89 
90 	if (!kobj || !buf)
91 		return -EINVAL;
92 
93 	if (efi.mps != EFI_INVALID_TABLE_ADDR)
94 		str += sprintf(str, "MPS=0x%lx\n", efi.mps);
95 	if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
96 		str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
97 	if (efi.acpi != EFI_INVALID_TABLE_ADDR)
98 		str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
99 	/*
100 	 * If both SMBIOS and SMBIOS3 entry points are implemented, the
101 	 * SMBIOS3 entry point shall be preferred, so we list it first to
102 	 * let applications stop parsing after the first match.
103 	 */
104 	if (efi.smbios3 != EFI_INVALID_TABLE_ADDR)
105 		str += sprintf(str, "SMBIOS3=0x%lx\n", efi.smbios3);
106 	if (efi.smbios != EFI_INVALID_TABLE_ADDR)
107 		str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
108 	if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
109 		str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
110 	if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
111 		str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
112 	if (efi.uga != EFI_INVALID_TABLE_ADDR)
113 		str += sprintf(str, "UGA=0x%lx\n", efi.uga);
114 
115 	return str - buf;
116 }
117 
118 static struct kobj_attribute efi_attr_systab =
119 			__ATTR(systab, 0400, systab_show, NULL);
120 
121 #define EFI_FIELD(var) efi.var
122 
123 #define EFI_ATTR_SHOW(name) \
124 static ssize_t name##_show(struct kobject *kobj, \
125 				struct kobj_attribute *attr, char *buf) \
126 { \
127 	return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
128 }
129 
130 EFI_ATTR_SHOW(fw_vendor);
131 EFI_ATTR_SHOW(runtime);
132 EFI_ATTR_SHOW(config_table);
133 
134 static ssize_t fw_platform_size_show(struct kobject *kobj,
135 				     struct kobj_attribute *attr, char *buf)
136 {
137 	return sprintf(buf, "%d\n", efi_enabled(EFI_64BIT) ? 64 : 32);
138 }
139 
140 static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
141 static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
142 static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
143 static struct kobj_attribute efi_attr_fw_platform_size =
144 	__ATTR_RO(fw_platform_size);
145 
146 static struct attribute *efi_subsys_attrs[] = {
147 	&efi_attr_systab.attr,
148 	&efi_attr_fw_vendor.attr,
149 	&efi_attr_runtime.attr,
150 	&efi_attr_config_table.attr,
151 	&efi_attr_fw_platform_size.attr,
152 	NULL,
153 };
154 
155 static umode_t efi_attr_is_visible(struct kobject *kobj,
156 				   struct attribute *attr, int n)
157 {
158 	if (attr == &efi_attr_fw_vendor.attr) {
159 		if (efi_enabled(EFI_PARAVIRT) ||
160 				efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
161 			return 0;
162 	} else if (attr == &efi_attr_runtime.attr) {
163 		if (efi.runtime == EFI_INVALID_TABLE_ADDR)
164 			return 0;
165 	} else if (attr == &efi_attr_config_table.attr) {
166 		if (efi.config_table == EFI_INVALID_TABLE_ADDR)
167 			return 0;
168 	}
169 
170 	return attr->mode;
171 }
172 
173 static struct attribute_group efi_subsys_attr_group = {
174 	.attrs = efi_subsys_attrs,
175 	.is_visible = efi_attr_is_visible,
176 };
177 
178 static struct efivars generic_efivars;
179 static struct efivar_operations generic_ops;
180 
181 static int generic_ops_register(void)
182 {
183 	generic_ops.get_variable = efi.get_variable;
184 	generic_ops.set_variable = efi.set_variable;
185 	generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
186 	generic_ops.get_next_variable = efi.get_next_variable;
187 	generic_ops.query_variable_store = efi_query_variable_store;
188 
189 	return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
190 }
191 
192 static void generic_ops_unregister(void)
193 {
194 	efivars_unregister(&generic_efivars);
195 }
196 
197 /*
198  * We register the efi subsystem with the firmware subsystem and the
199  * efivars subsystem with the efi subsystem, if the system was booted with
200  * EFI.
201  */
202 static int __init efisubsys_init(void)
203 {
204 	int error;
205 
206 	if (!efi_enabled(EFI_BOOT))
207 		return 0;
208 
209 	/* We register the efi directory at /sys/firmware/efi */
210 	efi_kobj = kobject_create_and_add("efi", firmware_kobj);
211 	if (!efi_kobj) {
212 		pr_err("efi: Firmware registration failed.\n");
213 		return -ENOMEM;
214 	}
215 
216 	error = generic_ops_register();
217 	if (error)
218 		goto err_put;
219 
220 	error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
221 	if (error) {
222 		pr_err("efi: Sysfs attribute export failed with error %d.\n",
223 		       error);
224 		goto err_unregister;
225 	}
226 
227 	error = efi_runtime_map_init(efi_kobj);
228 	if (error)
229 		goto err_remove_group;
230 
231 	/* and the standard mountpoint for efivarfs */
232 	error = sysfs_create_mount_point(efi_kobj, "efivars");
233 	if (error) {
234 		pr_err("efivars: Subsystem registration failed.\n");
235 		goto err_remove_group;
236 	}
237 
238 	return 0;
239 
240 err_remove_group:
241 	sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
242 err_unregister:
243 	generic_ops_unregister();
244 err_put:
245 	kobject_put(efi_kobj);
246 	return error;
247 }
248 
249 subsys_initcall(efisubsys_init);
250 
251 /*
252  * Find the efi memory descriptor for a given physical address.  Given a
253  * physicall address, determine if it exists within an EFI Memory Map entry,
254  * and if so, populate the supplied memory descriptor with the appropriate
255  * data.
256  */
257 int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
258 {
259 	struct efi_memory_map *map = efi.memmap;
260 	phys_addr_t p, e;
261 
262 	if (!efi_enabled(EFI_MEMMAP)) {
263 		pr_err_once("EFI_MEMMAP is not enabled.\n");
264 		return -EINVAL;
265 	}
266 
267 	if (!map) {
268 		pr_err_once("efi.memmap is not set.\n");
269 		return -EINVAL;
270 	}
271 	if (!out_md) {
272 		pr_err_once("out_md is null.\n");
273 		return -EINVAL;
274         }
275 	if (WARN_ON_ONCE(!map->phys_map))
276 		return -EINVAL;
277 	if (WARN_ON_ONCE(map->nr_map == 0) || WARN_ON_ONCE(map->desc_size == 0))
278 		return -EINVAL;
279 
280 	e = map->phys_map + map->nr_map * map->desc_size;
281 	for (p = map->phys_map; p < e; p += map->desc_size) {
282 		efi_memory_desc_t *md;
283 		u64 size;
284 		u64 end;
285 
286 		/*
287 		 * If a driver calls this after efi_free_boot_services,
288 		 * ->map will be NULL, and the target may also not be mapped.
289 		 * So just always get our own virtual map on the CPU.
290 		 *
291 		 */
292 		md = early_memremap(p, sizeof (*md));
293 		if (!md) {
294 			pr_err_once("early_memremap(%pa, %zu) failed.\n",
295 				    &p, sizeof (*md));
296 			return -ENOMEM;
297 		}
298 
299 		if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
300 		    md->type != EFI_BOOT_SERVICES_DATA &&
301 		    md->type != EFI_RUNTIME_SERVICES_DATA) {
302 			early_memunmap(md, sizeof (*md));
303 			continue;
304 		}
305 
306 		size = md->num_pages << EFI_PAGE_SHIFT;
307 		end = md->phys_addr + size;
308 		if (phys_addr >= md->phys_addr && phys_addr < end) {
309 			memcpy(out_md, md, sizeof(*out_md));
310 			early_memunmap(md, sizeof (*md));
311 			return 0;
312 		}
313 
314 		early_memunmap(md, sizeof (*md));
315 	}
316 	pr_err_once("requested map not found.\n");
317 	return -ENOENT;
318 }
319 
320 /*
321  * Calculate the highest address of an efi memory descriptor.
322  */
323 u64 __init efi_mem_desc_end(efi_memory_desc_t *md)
324 {
325 	u64 size = md->num_pages << EFI_PAGE_SHIFT;
326 	u64 end = md->phys_addr + size;
327 	return end;
328 }
329 
330 static __initdata efi_config_table_type_t common_tables[] = {
331 	{ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
332 	{ACPI_TABLE_GUID, "ACPI", &efi.acpi},
333 	{HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
334 	{MPS_TABLE_GUID, "MPS", &efi.mps},
335 	{SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab},
336 	{SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
337 	{SMBIOS3_TABLE_GUID, "SMBIOS 3.0", &efi.smbios3},
338 	{UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
339 	{EFI_SYSTEM_RESOURCE_TABLE_GUID, "ESRT", &efi.esrt},
340 	{EFI_PROPERTIES_TABLE_GUID, "PROP", &efi.properties_table},
341 	{NULL_GUID, NULL, NULL},
342 };
343 
344 static __init int match_config_table(efi_guid_t *guid,
345 				     unsigned long table,
346 				     efi_config_table_type_t *table_types)
347 {
348 	int i;
349 
350 	if (table_types) {
351 		for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
352 			if (!efi_guidcmp(*guid, table_types[i].guid)) {
353 				*(table_types[i].ptr) = table;
354 				pr_cont(" %s=0x%lx ",
355 					table_types[i].name, table);
356 				return 1;
357 			}
358 		}
359 	}
360 
361 	return 0;
362 }
363 
364 int __init efi_config_parse_tables(void *config_tables, int count, int sz,
365 				   efi_config_table_type_t *arch_tables)
366 {
367 	void *tablep;
368 	int i;
369 
370 	tablep = config_tables;
371 	pr_info("");
372 	for (i = 0; i < count; i++) {
373 		efi_guid_t guid;
374 		unsigned long table;
375 
376 		if (efi_enabled(EFI_64BIT)) {
377 			u64 table64;
378 			guid = ((efi_config_table_64_t *)tablep)->guid;
379 			table64 = ((efi_config_table_64_t *)tablep)->table;
380 			table = table64;
381 #ifndef CONFIG_64BIT
382 			if (table64 >> 32) {
383 				pr_cont("\n");
384 				pr_err("Table located above 4GB, disabling EFI.\n");
385 				return -EINVAL;
386 			}
387 #endif
388 		} else {
389 			guid = ((efi_config_table_32_t *)tablep)->guid;
390 			table = ((efi_config_table_32_t *)tablep)->table;
391 		}
392 
393 		if (!match_config_table(&guid, table, common_tables))
394 			match_config_table(&guid, table, arch_tables);
395 
396 		tablep += sz;
397 	}
398 	pr_cont("\n");
399 	set_bit(EFI_CONFIG_TABLES, &efi.flags);
400 
401 	/* Parse the EFI Properties table if it exists */
402 	if (efi.properties_table != EFI_INVALID_TABLE_ADDR) {
403 		efi_properties_table_t *tbl;
404 
405 		tbl = early_memremap(efi.properties_table, sizeof(*tbl));
406 		if (tbl == NULL) {
407 			pr_err("Could not map Properties table!\n");
408 			return -ENOMEM;
409 		}
410 
411 		if (tbl->memory_protection_attribute &
412 		    EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA)
413 			set_bit(EFI_NX_PE_DATA, &efi.flags);
414 
415 		early_memunmap(tbl, sizeof(*tbl));
416 	}
417 
418 	return 0;
419 }
420 
421 int __init efi_config_init(efi_config_table_type_t *arch_tables)
422 {
423 	void *config_tables;
424 	int sz, ret;
425 
426 	if (efi_enabled(EFI_64BIT))
427 		sz = sizeof(efi_config_table_64_t);
428 	else
429 		sz = sizeof(efi_config_table_32_t);
430 
431 	/*
432 	 * Let's see what config tables the firmware passed to us.
433 	 */
434 	config_tables = early_memremap(efi.systab->tables,
435 				       efi.systab->nr_tables * sz);
436 	if (config_tables == NULL) {
437 		pr_err("Could not map Configuration table!\n");
438 		return -ENOMEM;
439 	}
440 
441 	ret = efi_config_parse_tables(config_tables, efi.systab->nr_tables, sz,
442 				      arch_tables);
443 
444 	early_memunmap(config_tables, efi.systab->nr_tables * sz);
445 	return ret;
446 }
447 
448 #ifdef CONFIG_EFI_VARS_MODULE
449 static int __init efi_load_efivars(void)
450 {
451 	struct platform_device *pdev;
452 
453 	if (!efi_enabled(EFI_RUNTIME_SERVICES))
454 		return 0;
455 
456 	pdev = platform_device_register_simple("efivars", 0, NULL, 0);
457 	return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
458 }
459 device_initcall(efi_load_efivars);
460 #endif
461 
462 #ifdef CONFIG_EFI_PARAMS_FROM_FDT
463 
464 #define UEFI_PARAM(name, prop, field)			   \
465 	{						   \
466 		{ name },				   \
467 		{ prop },				   \
468 		offsetof(struct efi_fdt_params, field),    \
469 		FIELD_SIZEOF(struct efi_fdt_params, field) \
470 	}
471 
472 static __initdata struct {
473 	const char name[32];
474 	const char propname[32];
475 	int offset;
476 	int size;
477 } dt_params[] = {
478 	UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
479 	UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
480 	UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
481 	UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
482 	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
483 };
484 
485 struct param_info {
486 	int found;
487 	void *params;
488 };
489 
490 static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
491 				       int depth, void *data)
492 {
493 	struct param_info *info = data;
494 	const void *prop;
495 	void *dest;
496 	u64 val;
497 	int i, len;
498 
499 	if (depth != 1 || strcmp(uname, "chosen") != 0)
500 		return 0;
501 
502 	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
503 		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
504 		if (!prop)
505 			return 0;
506 		dest = info->params + dt_params[i].offset;
507 		info->found++;
508 
509 		val = of_read_number(prop, len / sizeof(u32));
510 
511 		if (dt_params[i].size == sizeof(u32))
512 			*(u32 *)dest = val;
513 		else
514 			*(u64 *)dest = val;
515 
516 		if (efi_enabled(EFI_DBG))
517 			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
518 				dt_params[i].size * 2, val);
519 	}
520 	return 1;
521 }
522 
523 int __init efi_get_fdt_params(struct efi_fdt_params *params)
524 {
525 	struct param_info info;
526 	int ret;
527 
528 	pr_info("Getting EFI parameters from FDT:\n");
529 
530 	info.found = 0;
531 	info.params = params;
532 
533 	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
534 	if (!info.found)
535 		pr_info("UEFI not found.\n");
536 	else if (!ret)
537 		pr_err("Can't find '%s' in device tree!\n",
538 		       dt_params[info.found].name);
539 
540 	return ret;
541 }
542 #endif /* CONFIG_EFI_PARAMS_FROM_FDT */
543 
544 static __initdata char memory_type_name[][20] = {
545 	"Reserved",
546 	"Loader Code",
547 	"Loader Data",
548 	"Boot Code",
549 	"Boot Data",
550 	"Runtime Code",
551 	"Runtime Data",
552 	"Conventional Memory",
553 	"Unusable Memory",
554 	"ACPI Reclaim Memory",
555 	"ACPI Memory NVS",
556 	"Memory Mapped I/O",
557 	"MMIO Port Space",
558 	"PAL Code",
559 	"Persistent Memory",
560 };
561 
562 char * __init efi_md_typeattr_format(char *buf, size_t size,
563 				     const efi_memory_desc_t *md)
564 {
565 	char *pos;
566 	int type_len;
567 	u64 attr;
568 
569 	pos = buf;
570 	if (md->type >= ARRAY_SIZE(memory_type_name))
571 		type_len = snprintf(pos, size, "[type=%u", md->type);
572 	else
573 		type_len = snprintf(pos, size, "[%-*s",
574 				    (int)(sizeof(memory_type_name[0]) - 1),
575 				    memory_type_name[md->type]);
576 	if (type_len >= size)
577 		return buf;
578 
579 	pos += type_len;
580 	size -= type_len;
581 
582 	attr = md->attribute;
583 	if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
584 		     EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
585 		     EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
586 		     EFI_MEMORY_NV |
587 		     EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
588 		snprintf(pos, size, "|attr=0x%016llx]",
589 			 (unsigned long long)attr);
590 	else
591 		snprintf(pos, size,
592 			 "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
593 			 attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
594 			 attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
595 			 attr & EFI_MEMORY_NV      ? "NV"  : "",
596 			 attr & EFI_MEMORY_XP      ? "XP"  : "",
597 			 attr & EFI_MEMORY_RP      ? "RP"  : "",
598 			 attr & EFI_MEMORY_WP      ? "WP"  : "",
599 			 attr & EFI_MEMORY_RO      ? "RO"  : "",
600 			 attr & EFI_MEMORY_UCE     ? "UCE" : "",
601 			 attr & EFI_MEMORY_WB      ? "WB"  : "",
602 			 attr & EFI_MEMORY_WT      ? "WT"  : "",
603 			 attr & EFI_MEMORY_WC      ? "WC"  : "",
604 			 attr & EFI_MEMORY_UC      ? "UC"  : "");
605 	return buf;
606 }
607 
608 /*
609  * efi_mem_attributes - lookup memmap attributes for physical address
610  * @phys_addr: the physical address to lookup
611  *
612  * Search in the EFI memory map for the region covering
613  * @phys_addr. Returns the EFI memory attributes if the region
614  * was found in the memory map, 0 otherwise.
615  *
616  * Despite being marked __weak, most architectures should *not*
617  * override this function. It is __weak solely for the benefit
618  * of ia64 which has a funky EFI memory map that doesn't work
619  * the same way as other architectures.
620  */
621 u64 __weak efi_mem_attributes(unsigned long phys_addr)
622 {
623 	struct efi_memory_map *map;
624 	efi_memory_desc_t *md;
625 	void *p;
626 
627 	if (!efi_enabled(EFI_MEMMAP))
628 		return 0;
629 
630 	map = efi.memmap;
631 	for (p = map->map; p < map->map_end; p += map->desc_size) {
632 		md = p;
633 		if ((md->phys_addr <= phys_addr) &&
634 		    (phys_addr < (md->phys_addr +
635 		    (md->num_pages << EFI_PAGE_SHIFT))))
636 			return md->attribute;
637 	}
638 	return 0;
639 }
640