WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] SeaBIOS/Xen: Compute the low RAM memory size in the

To: seabios@xxxxxxxxxxx
Subject: [Xen-devel] [PATCH] SeaBIOS/Xen: Compute the low RAM memory size in the BDA according to the e820
From: Julian Pidancet <julian.pidancet@xxxxxxxxx>
Date: Mon, 14 Nov 2011 01:50:05 +0000
Cc: xen-devel@xxxxxxxxxxxxxxxxxxx, kevin@xxxxxxxxxxxx, ian.campbell@xxxxxxxxxx, Julian Pidancet <julian.pidancet@xxxxxxxxx>
Delivery-date: Sun, 13 Nov 2011 16:59:33 -0800
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; bh=VqfICWm9vedSbXIovchKUV9GbevEZRDITzYxpwtjDes=; b=FLDX2fuu4AGvkz0AVqAk1zCBHmrrLDZmcd6I0LL5FSEO4k3w1/OX9KI0UHOxE1OGyo zIjqvtoNp2cnnJDsjPQDDIkYt6YdmTbFBsS60rPoKnCXxY80usQnz5eoQ06H8xfKK3fi 16j32XL1vU3vQ94JwkKZe8SdqUhWxBldhcMMs=
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Some programs or ROMs like iPXE rely on the memory size field present
in the BDA instead of e820 to relocate sections at the end of the low
memory.
Xen's hvmloader places an ACPI info table at 0x9F000 at the end of the
usable RAM in low memory (just before the EBDA). The e820 table gets
altered accordingly to protect the area where the table lives, but a ROM
like iPXE only takes into account the memory size field in the BDA and
consequently corrupts the table when relocating itself.

This patch computes the size of the usable RAM in low memory by walking
the e820 table and updates the BDA accordingly. It defaults to 640KB if
it fails to guess that value.

With Xen, the issue can be reproduced by pxe booting a linux kernel
through iPXE using the pci=use_crs command line option. Without this
patch the last of the following lines doesn't appear:

[    0.326967] PCI: Using host bridge windows from ACPI; if necessary, use 
"pci=nocrs" and report a bug
[    0.327999] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[    0.329028] pci_root PNP0A03:00: host bridge window [io  0x0000-0x0cf7]
[    0.329967] pci_root PNP0A03:00: host bridge window [io  0x0d00-0xffff]
[    0.330966] pci_root PNP0A03:00: host bridge window [mem 
0x000a0000-0x000bffff]
[    0.331966] pci_root PNP0A03:00: host bridge window [mem 
0xf0000000-0xfbffffff]

Signed-off-by: Julian Pidancet <julian.pidancet@xxxxxxxxx>
---
 src/memmap.c |   29 +++++++++++++++++++++++++++++
 src/memmap.h |    1 +
 src/post.c   |    9 ++++++---
 3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/src/memmap.c b/src/memmap.c
index 20ccae0..36750f5 100644
--- a/src/memmap.c
+++ b/src/memmap.c
@@ -7,6 +7,7 @@
 #include "memmap.h" // struct e820entry
 #include "util.h" // dprintf.h
 #include "biosvar.h" // SET_EBDA
+#include "config.h" // CONFIG_*
 
 
 /****************************************************************
@@ -133,6 +134,34 @@ add_e820(u64 start, u64 size, u32 type)
     //dump_map();
 }
 
+// Try to find the size of the usable RAM memory in the
+// first megabyte of RAM.
+u32
+get_lowram_size(void)
+{
+    u32 lowram_end = 0;
+
+    int i;
+    for (i=0; i<e820_count; i++) {
+        struct e820entry *e = &e820_list[i];
+        u64 e_end = e->start + e->size;
+
+        if (e->type != E820_RAM)
+            continue;
+
+        if (e_end <= 0x100000 && /* 1M */
+            e_end > lowram_end)
+            lowram_end = (u32)e_end;
+    }
+
+    // No RAM entry ending before the first megabyte of memory
+    // found, default to 0xA0000
+    if (!lowram_end)
+        lowram_end = BUILD_LOWRAM_END;
+
+    return lowram_end;
+}
+
 // Report on final memory locations.
 void
 memmap_finalize(void)
diff --git a/src/memmap.h b/src/memmap.h
index 01c7ddb..e65d090 100644
--- a/src/memmap.h
+++ b/src/memmap.h
@@ -18,6 +18,7 @@ struct e820entry {
 
 void add_e820(u64 start, u64 size, u32 type);
 void memmap_finalize(void);
+u32 get_lowram_size(void);
 
 // A typical OS page size
 #define PAGE_SIZE 4096
diff --git a/src/post.c b/src/post.c
index b4ad1fa..9f0cb63 100644
--- a/src/post.c
+++ b/src/post.c
@@ -82,18 +82,21 @@ init_bda(void)
     struct bios_data_area_s *bda = MAKE_FLATPTR(SEG_BDA, 0);
     memset(bda, 0, sizeof(*bda));
 
-    int esize = EBDA_SIZE_START;
-    SET_BDA(mem_size_kb, BUILD_LOWRAM_END/1024 - esize);
     u16 ebda_seg = EBDA_SEGMENT_START;
     SET_BDA(ebda_seg, ebda_seg);
 
     // Init ebda
     struct extended_bios_data_area_s *ebda = get_ebda_ptr();
     memset(ebda, 0, sizeof(*ebda));
-    ebda->size = esize;
+    ebda->size = EBDA_SIZE_START;
 
     add_e820((u32)MAKE_FLATPTR(ebda_seg, 0), GET_EBDA2(ebda_seg, size) * 1024
              , E820_RESERVED);
+
+    u32 lowram_size = get_lowram_size();
+
+    dprintf(8, "End of usable low memory RAM: %08x\n", lowram_size);
+    SET_BDA(mem_size_kb, lowram_size / 1024);
 }
 
 static void
-- 
Julian Pidancet


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel