aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/e820.c60
-rw-r--r--arch/i386/mm/init.c2
-rw-r--r--include/linux/efi.h1
3 files changed, 44 insertions, 19 deletions
diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c
index b704790f7969..2f7d0a92fd7c 100644
--- a/arch/i386/kernel/e820.c
+++ b/arch/i386/kernel/e820.c
@@ -742,29 +742,55 @@ void __init print_memory_map(char *who)
742 } 742 }
743} 743}
744 744
745void __init limit_regions(unsigned long long size) 745static __init __always_inline void efi_limit_regions(unsigned long long size)
746{ 746{
747 unsigned long long current_addr = 0; 747 unsigned long long current_addr = 0;
748 efi_memory_desc_t *md, *next_md;
749 void *p, *p1;
750 int i, j;
751
752 j = 0;
753 p1 = memmap.map;
754 for (p = p1, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) {
755 md = p;
756 next_md = p1;
757 current_addr = md->phys_addr +
758 PFN_PHYS(md->num_pages);
759 if (is_available_memory(md)) {
760 if (md->phys_addr >= size) continue;
761 memcpy(next_md, md, memmap.desc_size);
762 if (current_addr >= size) {
763 next_md->num_pages -=
764 PFN_UP(current_addr-size);
765 }
766 p1 += memmap.desc_size;
767 next_md = p1;
768 j++;
769 } else if ((md->attribute & EFI_MEMORY_RUNTIME) ==
770 EFI_MEMORY_RUNTIME) {
771 /* In order to make runtime services
772 * available we have to include runtime
773 * memory regions in memory map */
774 memcpy(next_md, md, memmap.desc_size);
775 p1 += memmap.desc_size;
776 next_md = p1;
777 j++;
778 }
779 }
780 memmap.nr_map = j;
781 memmap.map_end = memmap.map +
782 (memmap.nr_map * memmap.desc_size);
783}
784
785void __init limit_regions(unsigned long long size)
786{
787 unsigned long long current_addr;
748 int i; 788 int i;
749 789
750 print_memory_map("limit_regions start"); 790 print_memory_map("limit_regions start");
751 if (efi_enabled) { 791 if (efi_enabled) {
752 efi_memory_desc_t *md; 792 efi_limit_regions(size);
753 void *p; 793 return;
754
755 for (p = memmap.map, i = 0; p < memmap.map_end;
756 p += memmap.desc_size, i++) {
757 md = p;
758 current_addr = md->phys_addr + (md->num_pages << 12);
759 if (md->type == EFI_CONVENTIONAL_MEMORY) {
760 if (current_addr >= size) {
761 md->num_pages -=
762 (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT);
763 memmap.nr_map = i + 1;
764 return;
765 }
766 }
767 }
768 } 794 }
769 for (i = 0; i < e820.nr_map; i++) { 795 for (i = 0; i < e820.nr_map; i++) {
770 current_addr = e820.map[i].addr + e820.map[i].size; 796 current_addr = e820.map[i].addr + e820.map[i].size;
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 167416155ee4..f4dd048187ff 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -192,8 +192,6 @@ static inline int page_kills_ppro(unsigned long pagenr)
192 return 0; 192 return 0;
193} 193}
194 194
195extern int is_available_memory(efi_memory_desc_t *);
196
197int page_is_ram(unsigned long pagenr) 195int page_is_ram(unsigned long pagenr)
198{ 196{
199 int i; 197 int i;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 91ecf49fbf21..df1c91855f0e 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -302,6 +302,7 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource,
302 struct resource *data_resource); 302 struct resource *data_resource);
303extern unsigned long efi_get_time(void); 303extern unsigned long efi_get_time(void);
304extern int __init efi_set_rtc_mmss(unsigned long nowtime); 304extern int __init efi_set_rtc_mmss(unsigned long nowtime);
305extern int is_available_memory(efi_memory_desc_t * md);
305extern struct efi_memory_map memmap; 306extern struct efi_memory_map memmap;
306 307
307/** 308/**