diff options
author | Huang, Ying <ying.huang@intel.com> | 2008-01-30 07:31:19 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:31:19 -0500 |
commit | e429795c68d3001ecae74f6465420c9f043b0ece (patch) | |
tree | 46e24522c3b7fbe7dc9f7fc63b4c942ff48e4070 /arch/x86/kernel/efi_32.c | |
parent | 9ad65e4748f55e3159283d7fa9d54fb30c086113 (diff) |
x86: EFI runtime service support: remove duplicated code from efi_32.c
This patch removes the duplicated code between efi_32.c and efi.c.
Signed-off-by: Huang Ying <ying.huang@intel.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/efi_32.c')
-rw-r--r-- | arch/x86/kernel/efi_32.c | 430 |
1 files changed, 2 insertions, 428 deletions
diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c index 863e8926f2bb..1df13725e519 100644 --- a/arch/x86/kernel/efi_32.c +++ b/arch/x86/kernel/efi_32.c | |||
@@ -39,21 +39,8 @@ | |||
39 | #include <asm/desc.h> | 39 | #include <asm/desc.h> |
40 | #include <asm/tlbflush.h> | 40 | #include <asm/tlbflush.h> |
41 | 41 | ||
42 | #define EFI_DEBUG 0 | ||
43 | #define PFX "EFI: " | 42 | #define PFX "EFI: " |
44 | 43 | ||
45 | extern efi_status_t asmlinkage efi_call_phys(void *, ...); | ||
46 | |||
47 | struct efi efi; | ||
48 | EXPORT_SYMBOL(efi); | ||
49 | static struct efi efi_phys; | ||
50 | struct efi_memory_map memmap; | ||
51 | |||
52 | /* | ||
53 | * We require an early boot_ioremap mapping mechanism initially | ||
54 | */ | ||
55 | extern void * boot_ioremap(unsigned long, unsigned long); | ||
56 | |||
57 | /* | 44 | /* |
58 | * To make EFI call EFI runtime service in physical addressing mode we need | 45 | * To make EFI call EFI runtime service in physical addressing mode we need |
59 | * prelog/epilog before/after the invocation to disable interrupt, to | 46 | * prelog/epilog before/after the invocation to disable interrupt, to |
@@ -65,7 +52,7 @@ static unsigned long efi_rt_eflags; | |||
65 | static DEFINE_SPINLOCK(efi_rt_lock); | 52 | static DEFINE_SPINLOCK(efi_rt_lock); |
66 | static pgd_t efi_bak_pg_dir_pointer[2]; | 53 | static pgd_t efi_bak_pg_dir_pointer[2]; |
67 | 54 | ||
68 | static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) | 55 | void efi_call_phys_prelog(void) __acquires(efi_rt_lock) |
69 | { | 56 | { |
70 | unsigned long cr4; | 57 | unsigned long cr4; |
71 | unsigned long temp; | 58 | unsigned long temp; |
@@ -108,7 +95,7 @@ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) | |||
108 | load_gdt(&gdt_descr); | 95 | load_gdt(&gdt_descr); |
109 | } | 96 | } |
110 | 97 | ||
111 | static void efi_call_phys_epilog(void) __releases(efi_rt_lock) | 98 | void efi_call_phys_epilog(void) __releases(efi_rt_lock) |
112 | { | 99 | { |
113 | unsigned long cr4; | 100 | unsigned long cr4; |
114 | struct desc_ptr gdt_descr; | 101 | struct desc_ptr gdt_descr; |
@@ -138,87 +125,6 @@ static void efi_call_phys_epilog(void) __releases(efi_rt_lock) | |||
138 | spin_unlock(&efi_rt_lock); | 125 | spin_unlock(&efi_rt_lock); |
139 | } | 126 | } |
140 | 127 | ||
141 | static efi_status_t | ||
142 | phys_efi_set_virtual_address_map(unsigned long memory_map_size, | ||
143 | unsigned long descriptor_size, | ||
144 | u32 descriptor_version, | ||
145 | efi_memory_desc_t *virtual_map) | ||
146 | { | ||
147 | efi_status_t status; | ||
148 | |||
149 | efi_call_phys_prelog(); | ||
150 | status = efi_call_phys(efi_phys.set_virtual_address_map, | ||
151 | memory_map_size, descriptor_size, | ||
152 | descriptor_version, virtual_map); | ||
153 | efi_call_phys_epilog(); | ||
154 | return status; | ||
155 | } | ||
156 | |||
157 | static efi_status_t | ||
158 | phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) | ||
159 | { | ||
160 | efi_status_t status; | ||
161 | |||
162 | efi_call_phys_prelog(); | ||
163 | status = efi_call_phys(efi_phys.get_time, tm, tc); | ||
164 | efi_call_phys_epilog(); | ||
165 | return status; | ||
166 | } | ||
167 | |||
168 | inline int efi_set_rtc_mmss(unsigned long nowtime) | ||
169 | { | ||
170 | int real_seconds, real_minutes; | ||
171 | efi_status_t status; | ||
172 | efi_time_t eft; | ||
173 | efi_time_cap_t cap; | ||
174 | |||
175 | spin_lock(&efi_rt_lock); | ||
176 | status = efi.get_time(&eft, &cap); | ||
177 | spin_unlock(&efi_rt_lock); | ||
178 | if (status != EFI_SUCCESS) | ||
179 | panic("Ooops, efitime: can't read time!\n"); | ||
180 | real_seconds = nowtime % 60; | ||
181 | real_minutes = nowtime / 60; | ||
182 | |||
183 | if (((abs(real_minutes - eft.minute) + 15)/30) & 1) | ||
184 | real_minutes += 30; | ||
185 | real_minutes %= 60; | ||
186 | |||
187 | eft.minute = real_minutes; | ||
188 | eft.second = real_seconds; | ||
189 | |||
190 | if (status != EFI_SUCCESS) { | ||
191 | printk("Ooops: efitime: can't read time!\n"); | ||
192 | return -1; | ||
193 | } | ||
194 | return 0; | ||
195 | } | ||
196 | /* | ||
197 | * This is used during kernel init before runtime | ||
198 | * services have been remapped and also during suspend, therefore, | ||
199 | * we'll need to call both in physical and virtual modes. | ||
200 | */ | ||
201 | inline unsigned long efi_get_time(void) | ||
202 | { | ||
203 | efi_status_t status; | ||
204 | efi_time_t eft; | ||
205 | efi_time_cap_t cap; | ||
206 | |||
207 | if (efi.get_time) { | ||
208 | /* if we are in virtual mode use remapped function */ | ||
209 | status = efi.get_time(&eft, &cap); | ||
210 | } else { | ||
211 | /* we are in physical mode */ | ||
212 | status = phys_efi_get_time(&eft, &cap); | ||
213 | } | ||
214 | |||
215 | if (status != EFI_SUCCESS) | ||
216 | printk("Oops: efitime: can't read time status: 0x%lx\n",status); | ||
217 | |||
218 | return mktime(eft.year, eft.month, eft.day, eft.hour, | ||
219 | eft.minute, eft.second); | ||
220 | } | ||
221 | |||
222 | int is_available_memory(efi_memory_desc_t * md) | 128 | int is_available_memory(efi_memory_desc_t * md) |
223 | { | 129 | { |
224 | if (!(md->attribute & EFI_MEMORY_WB)) | 130 | if (!(md->attribute & EFI_MEMORY_WB)) |
@@ -250,24 +156,6 @@ void __init efi_map_memmap(void) | |||
250 | memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); | 156 | memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); |
251 | } | 157 | } |
252 | 158 | ||
253 | #if EFI_DEBUG | ||
254 | static void __init print_efi_memmap(void) | ||
255 | { | ||
256 | efi_memory_desc_t *md; | ||
257 | void *p; | ||
258 | int i; | ||
259 | |||
260 | for (p = memmap.map, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) { | ||
261 | md = p; | ||
262 | printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, " | ||
263 | "range=[0x%016llx-0x%016llx) (%lluMB)\n", | ||
264 | i, md->type, md->attribute, md->phys_addr, | ||
265 | md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), | ||
266 | (md->num_pages >> (20 - EFI_PAGE_SHIFT))); | ||
267 | } | ||
268 | } | ||
269 | #endif /* EFI_DEBUG */ | ||
270 | |||
271 | /* | 159 | /* |
272 | * Walks the EFI memory map and calls CALLBACK once for each EFI | 160 | * Walks the EFI memory map and calls CALLBACK once for each EFI |
273 | * memory descriptor that has memory that is available for kernel use. | 161 | * memory descriptor that has memory that is available for kernel use. |
@@ -319,288 +207,6 @@ void efi_memmap_walk(efi_freemem_callback_t callback, void *arg) | |||
319 | } | 207 | } |
320 | } | 208 | } |
321 | 209 | ||
322 | void __init efi_init(void) | ||
323 | { | ||
324 | efi_config_table_t *config_tables; | ||
325 | efi_runtime_services_t *runtime; | ||
326 | efi_char16_t *c16; | ||
327 | char vendor[100] = "unknown"; | ||
328 | unsigned long num_config_tables; | ||
329 | int i = 0; | ||
330 | |||
331 | memset(&efi, 0, sizeof(efi) ); | ||
332 | memset(&efi_phys, 0, sizeof(efi_phys)); | ||
333 | |||
334 | efi_phys.systab = | ||
335 | (efi_system_table_t *)boot_params.efi_info.efi_systab; | ||
336 | memmap.phys_map = (void *)boot_params.efi_info.efi_memmap; | ||
337 | memmap.nr_map = boot_params.efi_info.efi_memmap_size/ | ||
338 | boot_params.efi_info.efi_memdesc_size; | ||
339 | memmap.desc_version = boot_params.efi_info.efi_memdesc_version; | ||
340 | memmap.desc_size = boot_params.efi_info.efi_memdesc_size; | ||
341 | |||
342 | efi.systab = (efi_system_table_t *) | ||
343 | boot_ioremap((unsigned long) efi_phys.systab, | ||
344 | sizeof(efi_system_table_t)); | ||
345 | /* | ||
346 | * Verify the EFI Table | ||
347 | */ | ||
348 | if (efi.systab == NULL) | ||
349 | printk(KERN_ERR PFX "Woah! Couldn't map the EFI system table.\n"); | ||
350 | if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) | ||
351 | printk(KERN_ERR PFX "Woah! EFI system table signature incorrect\n"); | ||
352 | if ((efi.systab->hdr.revision >> 16) == 0) | ||
353 | printk(KERN_ERR PFX "Warning: EFI system table version " | ||
354 | "%d.%02d, expected 1.00 or greater\n", | ||
355 | efi.systab->hdr.revision >> 16, | ||
356 | efi.systab->hdr.revision & 0xffff); | ||
357 | |||
358 | /* | ||
359 | * Grab some details from the system table | ||
360 | */ | ||
361 | num_config_tables = efi.systab->nr_tables; | ||
362 | config_tables = (efi_config_table_t *)efi.systab->tables; | ||
363 | runtime = efi.systab->runtime; | ||
364 | |||
365 | /* | ||
366 | * Show what we know for posterity | ||
367 | */ | ||
368 | c16 = (efi_char16_t *) boot_ioremap(efi.systab->fw_vendor, 2); | ||
369 | if (c16) { | ||
370 | for (i = 0; i < (sizeof(vendor) - 1) && *c16; ++i) | ||
371 | vendor[i] = *c16++; | ||
372 | vendor[i] = '\0'; | ||
373 | } else | ||
374 | printk(KERN_ERR PFX "Could not map the firmware vendor!\n"); | ||
375 | |||
376 | printk(KERN_INFO PFX "EFI v%u.%.02u by %s \n", | ||
377 | efi.systab->hdr.revision >> 16, | ||
378 | efi.systab->hdr.revision & 0xffff, vendor); | ||
379 | |||
380 | /* | ||
381 | * Let's see what config tables the firmware passed to us. | ||
382 | */ | ||
383 | config_tables = (efi_config_table_t *) | ||
384 | boot_ioremap((unsigned long) config_tables, | ||
385 | num_config_tables * sizeof(efi_config_table_t)); | ||
386 | |||
387 | if (config_tables == NULL) | ||
388 | printk(KERN_ERR PFX "Could not map EFI Configuration Table!\n"); | ||
389 | |||
390 | efi.mps = EFI_INVALID_TABLE_ADDR; | ||
391 | efi.acpi = EFI_INVALID_TABLE_ADDR; | ||
392 | efi.acpi20 = EFI_INVALID_TABLE_ADDR; | ||
393 | efi.smbios = EFI_INVALID_TABLE_ADDR; | ||
394 | efi.sal_systab = EFI_INVALID_TABLE_ADDR; | ||
395 | efi.boot_info = EFI_INVALID_TABLE_ADDR; | ||
396 | efi.hcdp = EFI_INVALID_TABLE_ADDR; | ||
397 | efi.uga = EFI_INVALID_TABLE_ADDR; | ||
398 | |||
399 | for (i = 0; i < num_config_tables; i++) { | ||
400 | if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) { | ||
401 | efi.mps = config_tables[i].table; | ||
402 | printk(KERN_INFO " MPS=0x%lx ", config_tables[i].table); | ||
403 | } else | ||
404 | if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) { | ||
405 | efi.acpi20 = config_tables[i].table; | ||
406 | printk(KERN_INFO " ACPI 2.0=0x%lx ", config_tables[i].table); | ||
407 | } else | ||
408 | if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) { | ||
409 | efi.acpi = config_tables[i].table; | ||
410 | printk(KERN_INFO " ACPI=0x%lx ", config_tables[i].table); | ||
411 | } else | ||
412 | if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) { | ||
413 | efi.smbios = config_tables[i].table; | ||
414 | printk(KERN_INFO " SMBIOS=0x%lx ", config_tables[i].table); | ||
415 | } else | ||
416 | if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) { | ||
417 | efi.hcdp = config_tables[i].table; | ||
418 | printk(KERN_INFO " HCDP=0x%lx ", config_tables[i].table); | ||
419 | } else | ||
420 | if (efi_guidcmp(config_tables[i].guid, UGA_IO_PROTOCOL_GUID) == 0) { | ||
421 | efi.uga = config_tables[i].table; | ||
422 | printk(KERN_INFO " UGA=0x%lx ", config_tables[i].table); | ||
423 | } | ||
424 | } | ||
425 | printk("\n"); | ||
426 | |||
427 | /* | ||
428 | * Check out the runtime services table. We need to map | ||
429 | * the runtime services table so that we can grab the physical | ||
430 | * address of several of the EFI runtime functions, needed to | ||
431 | * set the firmware into virtual mode. | ||
432 | */ | ||
433 | |||
434 | runtime = (efi_runtime_services_t *) boot_ioremap((unsigned long) | ||
435 | runtime, | ||
436 | sizeof(efi_runtime_services_t)); | ||
437 | if (runtime != NULL) { | ||
438 | /* | ||
439 | * We will only need *early* access to the following | ||
440 | * two EFI runtime services before set_virtual_address_map | ||
441 | * is invoked. | ||
442 | */ | ||
443 | efi_phys.get_time = (efi_get_time_t *) runtime->get_time; | ||
444 | efi_phys.set_virtual_address_map = | ||
445 | (efi_set_virtual_address_map_t *) | ||
446 | runtime->set_virtual_address_map; | ||
447 | } else | ||
448 | printk(KERN_ERR PFX "Could not map the runtime service table!\n"); | ||
449 | |||
450 | /* Map the EFI memory map for use until paging_init() */ | ||
451 | memmap.map = boot_ioremap(boot_params.efi_info.efi_memmap, | ||
452 | boot_params.efi_info.efi_memmap_size); | ||
453 | if (memmap.map == NULL) | ||
454 | printk(KERN_ERR PFX "Could not map the EFI memory map!\n"); | ||
455 | |||
456 | memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); | ||
457 | |||
458 | #if EFI_DEBUG | ||
459 | print_efi_memmap(); | ||
460 | #endif | ||
461 | } | ||
462 | |||
463 | static inline void __init check_range_for_systab(efi_memory_desc_t *md) | ||
464 | { | ||
465 | if (((unsigned long)md->phys_addr <= (unsigned long)efi_phys.systab) && | ||
466 | ((unsigned long)efi_phys.systab < md->phys_addr + | ||
467 | ((unsigned long)md->num_pages << EFI_PAGE_SHIFT))) { | ||
468 | unsigned long addr; | ||
469 | |||
470 | addr = md->virt_addr - md->phys_addr + | ||
471 | (unsigned long)efi_phys.systab; | ||
472 | efi.systab = (efi_system_table_t *)addr; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | /* | ||
477 | * Wrap all the virtual calls in a way that forces the parameters on the stack. | ||
478 | */ | ||
479 | |||
480 | #define efi_call_virt(f, args...) \ | ||
481 | ((efi_##f##_t __attribute__((regparm(0)))*)efi.systab->runtime->f)(args) | ||
482 | |||
483 | static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) | ||
484 | { | ||
485 | return efi_call_virt(get_time, tm, tc); | ||
486 | } | ||
487 | |||
488 | static efi_status_t virt_efi_set_time (efi_time_t *tm) | ||
489 | { | ||
490 | return efi_call_virt(set_time, tm); | ||
491 | } | ||
492 | |||
493 | static efi_status_t virt_efi_get_wakeup_time (efi_bool_t *enabled, | ||
494 | efi_bool_t *pending, | ||
495 | efi_time_t *tm) | ||
496 | { | ||
497 | return efi_call_virt(get_wakeup_time, enabled, pending, tm); | ||
498 | } | ||
499 | |||
500 | static efi_status_t virt_efi_set_wakeup_time (efi_bool_t enabled, | ||
501 | efi_time_t *tm) | ||
502 | { | ||
503 | return efi_call_virt(set_wakeup_time, enabled, tm); | ||
504 | } | ||
505 | |||
506 | static efi_status_t virt_efi_get_variable (efi_char16_t *name, | ||
507 | efi_guid_t *vendor, u32 *attr, | ||
508 | unsigned long *data_size, void *data) | ||
509 | { | ||
510 | return efi_call_virt(get_variable, name, vendor, attr, data_size, data); | ||
511 | } | ||
512 | |||
513 | static efi_status_t virt_efi_get_next_variable (unsigned long *name_size, | ||
514 | efi_char16_t *name, | ||
515 | efi_guid_t *vendor) | ||
516 | { | ||
517 | return efi_call_virt(get_next_variable, name_size, name, vendor); | ||
518 | } | ||
519 | |||
520 | static efi_status_t virt_efi_set_variable (efi_char16_t *name, | ||
521 | efi_guid_t *vendor, | ||
522 | unsigned long attr, | ||
523 | unsigned long data_size, void *data) | ||
524 | { | ||
525 | return efi_call_virt(set_variable, name, vendor, attr, data_size, data); | ||
526 | } | ||
527 | |||
528 | static efi_status_t virt_efi_get_next_high_mono_count (u32 *count) | ||
529 | { | ||
530 | return efi_call_virt(get_next_high_mono_count, count); | ||
531 | } | ||
532 | |||
533 | static void virt_efi_reset_system (int reset_type, efi_status_t status, | ||
534 | unsigned long data_size, | ||
535 | efi_char16_t *data) | ||
536 | { | ||
537 | efi_call_virt(reset_system, reset_type, status, data_size, data); | ||
538 | } | ||
539 | |||
540 | /* | ||
541 | * This function will switch the EFI runtime services to virtual mode. | ||
542 | * Essentially, look through the EFI memmap and map every region that | ||
543 | * has the runtime attribute bit set in its memory descriptor and update | ||
544 | * that memory descriptor with the virtual address obtained from ioremap(). | ||
545 | * This enables the runtime services to be called without having to | ||
546 | * thunk back into physical mode for every invocation. | ||
547 | */ | ||
548 | |||
549 | void __init efi_enter_virtual_mode(void) | ||
550 | { | ||
551 | efi_memory_desc_t *md; | ||
552 | efi_status_t status; | ||
553 | void *p; | ||
554 | |||
555 | efi.systab = NULL; | ||
556 | |||
557 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
558 | md = p; | ||
559 | |||
560 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) | ||
561 | continue; | ||
562 | |||
563 | md->virt_addr = (unsigned long)ioremap(md->phys_addr, | ||
564 | md->num_pages << EFI_PAGE_SHIFT); | ||
565 | if (!(unsigned long)md->virt_addr) { | ||
566 | printk(KERN_ERR PFX "ioremap of 0x%lX failed\n", | ||
567 | (unsigned long)md->phys_addr); | ||
568 | } | ||
569 | /* update the virtual address of the EFI system table */ | ||
570 | check_range_for_systab(md); | ||
571 | } | ||
572 | |||
573 | BUG_ON(!efi.systab); | ||
574 | |||
575 | status = phys_efi_set_virtual_address_map( | ||
576 | memmap.desc_size * memmap.nr_map, | ||
577 | memmap.desc_size, | ||
578 | memmap.desc_version, | ||
579 | memmap.phys_map); | ||
580 | |||
581 | if (status != EFI_SUCCESS) { | ||
582 | printk (KERN_ALERT "You are screwed! " | ||
583 | "Unable to switch EFI into virtual mode " | ||
584 | "(status=%lx)\n", status); | ||
585 | panic("EFI call to SetVirtualAddressMap() failed!"); | ||
586 | } | ||
587 | |||
588 | /* | ||
589 | * Now that EFI is in virtual mode, update the function | ||
590 | * pointers in the runtime service table to the new virtual addresses. | ||
591 | */ | ||
592 | |||
593 | efi.get_time = virt_efi_get_time; | ||
594 | efi.set_time = virt_efi_set_time; | ||
595 | efi.get_wakeup_time = virt_efi_get_wakeup_time; | ||
596 | efi.set_wakeup_time = virt_efi_set_wakeup_time; | ||
597 | efi.get_variable = virt_efi_get_variable; | ||
598 | efi.get_next_variable = virt_efi_get_next_variable; | ||
599 | efi.set_variable = virt_efi_set_variable; | ||
600 | efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; | ||
601 | efi.reset_system = virt_efi_reset_system; | ||
602 | } | ||
603 | |||
604 | void __init | 210 | void __init |
605 | efi_initialize_iomem_resources(struct resource *code_resource, | 211 | efi_initialize_iomem_resources(struct resource *code_resource, |
606 | struct resource *data_resource, | 212 | struct resource *data_resource, |
@@ -683,35 +289,3 @@ efi_initialize_iomem_resources(struct resource *code_resource, | |||
683 | } | 289 | } |
684 | } | 290 | } |
685 | } | 291 | } |
686 | |||
687 | /* | ||
688 | * Convenience functions to obtain memory types and attributes | ||
689 | */ | ||
690 | |||
691 | u32 efi_mem_type(unsigned long phys_addr) | ||
692 | { | ||
693 | efi_memory_desc_t *md; | ||
694 | void *p; | ||
695 | |||
696 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
697 | md = p; | ||
698 | if ((md->phys_addr <= phys_addr) && (phys_addr < | ||
699 | (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) | ||
700 | return md->type; | ||
701 | } | ||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | u64 efi_mem_attributes(unsigned long phys_addr) | ||
706 | { | ||
707 | efi_memory_desc_t *md; | ||
708 | void *p; | ||
709 | |||
710 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
711 | md = p; | ||
712 | if ((md->phys_addr <= phys_addr) && (phys_addr < | ||
713 | (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) | ||
714 | return md->attribute; | ||
715 | } | ||
716 | return 0; | ||
717 | } | ||