diff --git a/Makefile b/Makefile
index 4b76b55..06b60fc 100644
--- a/Makefile
+++ b/Makefile
@@ -41,6 +41,7 @@ src-$(CONFIG_TPMFRONT) += tpmfront.c
 src-$(CONFIG_TPM_TIS) += tpm_tis.c
 src-$(CONFIG_TPMBACK) += tpmback.c
 src-y += daytime.c
+src-y += e820.c
 src-y += events.c
 src-$(CONFIG_FBFRONT) += fbfront.c
 src-y += gntmap.c
diff --git a/arch/arm/mm.c b/arch/arm/mm.c
index f806c9f..9068166 100644
--- a/arch/arm/mm.c
+++ b/arch/arm/mm.c
@@ -7,14 +7,6 @@
 #include <lib.h>
 
 uint32_t physical_address_offset;
-struct e820entry e820_map[1] = {
-    {
-        .addr = 0,
-        .size = ULONG_MAX - 1,
-        .type = E820_RAM
-    }
-};
-unsigned e820_entries = 1;
 
 unsigned long allocate_ondemand(unsigned long n, unsigned long alignment)
 {
diff --git a/arch/x86/mm.c b/arch/x86/mm.c
index 8ba14a5..8df93da 100644
--- a/arch/x86/mm.c
+++ b/arch/x86/mm.c
@@ -64,15 +64,6 @@ extern char stack[];
 extern void page_walk(unsigned long va);
 
 #ifdef CONFIG_PARAVIRT
-struct e820entry e820_map[1] = {
-    {
-        .addr = 0,
-        .size = ULONG_MAX - 1,
-        .type = E820_RAM
-    }
-};
-unsigned e820_entries = 1;
-
 void arch_mm_preinit(void *p)
 {
     start_info_t *si = p;
@@ -112,25 +103,11 @@ desc_ptr idt_ptr =
     .base = (unsigned long)&idt,
 };
 
-struct e820entry e820_map[E820_MAX];
-unsigned e820_entries;
-
-static char *e820_types[E820_TYPES] = {
-    [E820_RAM]      = "RAM",
-    [E820_RESERVED] = "Reserved",
-    [E820_ACPI]     = "ACPI",
-    [E820_NVS]      = "NVS",
-    [E820_UNUSABLE] = "Unusable",
-    [E820_PMEM]     = "PMEM"
-};
-
 void arch_mm_preinit(void *p)
 {
     long ret;
     domid_t domid = DOMID_SELF;
-    struct xen_memory_map memmap;
-    int i;
-    unsigned long pfn, max = 0;
+    unsigned long max;
 
     pt_base = page_table_base;
     first_free_pfn = PFN_UP(to_phys(&_end));
@@ -142,53 +119,10 @@ void arch_mm_preinit(void *p)
     }
     last_free_pfn = ret;
 
-    memmap.nr_entries = E820_MAX;
-    set_xen_guest_handle(memmap.buffer, e820_map);
-    ret = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
-    if ( ret < 0 )
-    {
-        xprintk("could not get memory map\n");
-        do_exit();
-    }
-    e820_entries = memmap.nr_entries;
-
-    for ( i = 0; i < e820_entries; i++ )
-    {
-        if ( e820_map[i].type != E820_RAM )
-            continue;
-        pfn = (e820_map[i].addr + e820_map[i].size) >> PAGE_SHIFT;
-        if ( pfn > max )
-            max = pfn;
-    }
-
+    max = e820_get_maxpfn();
     if ( max < last_free_pfn )
         last_free_pfn = max;
 }
-
-void arch_print_memmap(void)
-{
-    int i;
-    unsigned long from, to;
-    char *type;
-    char buf[12];
-
-    printk("Memory map:\n");
-    for ( i = 0; i < e820_entries; i++ )
-    {
-        if ( e820_map[i].type >= E820_TYPES || !e820_types[e820_map[i].type] )
-        {
-            snprintf(buf, sizeof(buf), "%8x", e820_map[i].type);
-            type = buf;
-        }
-        else
-        {
-            type = e820_types[e820_map[i].type];
-        }
-        from = e820_map[i].addr;
-        to = from + e820_map[i].size - 1;
-        printk("%012lx-%012lx: %s\n", from, to, type);
-    }
-}
 #endif
 
 /*
diff --git a/e820.c b/e820.c
new file mode 100644
index 0000000..2165280
--- /dev/null
+++ b/e820.c
@@ -0,0 +1,119 @@
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
+ *
+ * (C) 2021 - Juergen Gross, SUSE Software Solutions Germany GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <mini-os/types.h>
+#include <mini-os/lib.h>
+#include <mini-os/console.h>
+#include <mini-os/os.h>
+#include <mini-os/posix/limits.h>
+#include <mini-os/e820.h>
+#include <xen/memory.h>
+
+#ifdef CONFIG_E820_TRIVIAL
+struct e820entry e820_map[1] = {
+    {
+        .addr = 0,
+        .size = ULONG_MAX - 1,
+        .type = E820_RAM
+    }
+};
+
+unsigned e820_entries = 1;
+
+static void e820_get_memmap(void)
+{
+}
+
+#else
+struct e820entry e820_map[E820_MAX];
+unsigned e820_entries;
+
+static char *e820_types[E820_TYPES] = {
+    [E820_RAM]      = "RAM",
+    [E820_RESERVED] = "Reserved",
+    [E820_ACPI]     = "ACPI",
+    [E820_NVS]      = "NVS",
+    [E820_UNUSABLE] = "Unusable",
+    [E820_PMEM]     = "PMEM"
+};
+
+static void e820_get_memmap(void)
+{
+    long ret;
+    struct xen_memory_map memmap;
+
+    memmap.nr_entries = E820_MAX;
+    set_xen_guest_handle(memmap.buffer, e820_map);
+    ret = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
+    if ( ret < 0 )
+    {
+        xprintk("could not get memory map\n");
+        do_exit();
+    }
+    e820_entries = memmap.nr_entries;
+}
+
+void arch_print_memmap(void)
+{
+    int i;
+    unsigned long from, to;
+    char *type;
+    char buf[12];
+
+    printk("Memory map:\n");
+    for ( i = 0; i < e820_entries; i++ )
+    {
+        if ( e820_map[i].type >= E820_TYPES || !e820_types[e820_map[i].type] )
+        {
+            snprintf(buf, sizeof(buf), "%8x", e820_map[i].type);
+            type = buf;
+        }
+        else
+        {
+            type = e820_types[e820_map[i].type];
+        }
+        from = e820_map[i].addr;
+        to = from + e820_map[i].size - 1;
+        printk("%012lx-%012lx: %s\n", from, to, type);
+    }
+}
+#endif
+
+unsigned long e820_get_maxpfn(void)
+{
+    int i;
+    unsigned long pfn, max = 0;
+
+    e820_get_memmap();
+
+    for ( i = 0; i < e820_entries; i++ )
+    {
+        if ( e820_map[i].type != E820_RAM )
+            continue;
+        pfn = (e820_map[i].addr + e820_map[i].size) >> PAGE_SHIFT;
+        if ( pfn > max )
+            max = pfn;
+    }
+
+    return max;
+}
diff --git a/include/e820.h b/include/e820.h
index 920551c..af2129f 100644
--- a/include/e820.h
+++ b/include/e820.h
@@ -24,6 +24,10 @@
 #ifndef __E820_HEADER
 #define __E820_HEADER
 
+#if defined(__arm__) || defined(__aarch64__) || defined(CONFIG_PARAVIRT)
+#define CONFIG_E820_TRIVIAL
+#endif
+
 /* PC BIOS standard E820 types and structure. */
 #define E820_RAM          1
 #define E820_RESERVED     2
@@ -45,4 +49,6 @@ struct __packed e820entry {
 extern struct e820entry e820_map[];
 extern unsigned e820_entries;
 
+unsigned long e820_get_maxpfn(void);
+
 #endif /*__E820_HEADER*/
