aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtiom Myaskouvskey <artiom.myaskouvskey@intel.com>2006-12-06 20:14:11 -0500
committerAndi Kleen <andi@basil.nowhere.org>2006-12-06 20:14:11 -0500
commitbf7e6a196318316e921f357557fca9d11d15f486 (patch)
tree7484602fdde8eab3b750b4e9bd3f3d9a2edc628e
parentf990fff427d68af3e4e1d16fe799c106abc0bf53 (diff)
[PATCH] i386: Preserve EFI run time regions with memmap parameter
When using memmap kernel parameter in EFI boot we should also add to memory map memory regions of runtime services to enable their mapping later. AK: merged and cleaned up the patch Signed-off-by: Artiom Myaskouvskey <artiom.myaskouvskey@intel.com> Signed-off-by: Andi Kleen <ak@suse.de>
-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/**