aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/e820.c
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 /arch/i386/kernel/e820.c
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>
Diffstat (limited to 'arch/i386/kernel/e820.c')
-rw-r--r--arch/i386/kernel/e820.c60
1 files changed, 43 insertions, 17 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;