[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCHv6 23/37] plat/kvm: Parse memory info from device tree for Arm64


  • To: <minios-devel@xxxxxxxxxxxxxxxxxxxx>, <simon.kuenzer@xxxxxxxxx>
  • From: Wei Chen <wei.chen@xxxxxxx>
  • Date: Fri, 14 Sep 2018 07:56:56 +0000
  • Authentication-results: spf=pass (sender IP is 40.67.248.234) smtp.mailfrom=arm.com; lists.xenproject.org; dkim=none (message not signed) header.d=none;lists.xenproject.org; dmarc=bestguesspass action=none header.from=arm.com;
  • Cc: Kaly.Xin@xxxxxxx, nd@xxxxxxx, wei.chen@xxxxxxx
  • Delivery-date: Fri, 14 Sep 2018 07:58:40 +0000
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>
  • Nodisclaimer: True
  • Spamdiagnosticmetadata: NSPM
  • Spamdiagnosticoutput: 1:99

From: Wei Chen <Wei.Chen@xxxxxxx>

QEMU/KVM will store the memory informations like memory
region, memory base address and memory size to device
tree. We parse these informations for memory allocater and
new stack setting. QEMU/KVM will always provide us at least
one bank of memory and unikraft will use the first bank for
the time-being. So currently we only supported one bank.

Signed-off-by: Wei Chen <Wei.Chen@xxxxxxx>
---
 plat/kvm/arm/setup.c | 76 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/plat/kvm/arm/setup.c b/plat/kvm/arm/setup.c
index d59956a..4fb6515 100644
--- a/plat/kvm/arm/setup.c
+++ b/plat/kvm/arm/setup.c
@@ -21,7 +21,13 @@
 #include <libfdt.h>
 #include <kvm/console.h>
 #include <uk/assert.h>
+#include <kvm-arm/mm.h>
+#include <uk/arch/limits.h>
 
+void *_libkvmplat_pagetable;
+void *_libkvmplat_heap_start;
+void *_libkvmplat_stack_top;
+void *_libkvmplat_mem_end;
 void *_libkvmplat_dtb;
 
 #define MAX_CMDLINE_SIZE 1024
@@ -38,6 +44,68 @@ static void _init_dtb(void *dtb_pointer)
        uk_printd(DLVL_INFO, "Found device tree on: %p\n", dtb_pointer);
 }
 
+static void _init_dtb_mem(void)
+{
+       extern char _text[];
+       extern char _end[];
+       int fdt_mem, prop_len = 0, prop_min_len;
+       int naddr, nsize;
+       const uint64_t *regs;
+       uint64_t mem_base, mem_size, max_addr;
+
+       /* search for assigned VM memory in DTB */
+       if (fdt_num_mem_rsv(_libkvmplat_dtb) != 0)
+               uk_printd(DLVL_WARN, "Reserved memory is not supported\n");
+
+       fdt_mem = fdt_node_offset_by_prop_value(_libkvmplat_dtb, -1,
+                                               "device_type",
+                                               "memory", sizeof("memory"));
+       if (fdt_mem < 0) {
+               uk_printd(DLVL_WARN, "No memory found in DTB\n");
+               return;
+       }
+
+       naddr = fdt_address_cells(_libkvmplat_dtb, fdt_mem);
+       if (naddr < 0 || naddr >= FDT_MAX_NCELLS)
+               UK_CRASH("Could not find proper address cells!\n");
+
+       nsize = fdt_size_cells(_libkvmplat_dtb, fdt_mem);
+       if (nsize < 0 || nsize >= FDT_MAX_NCELLS)
+               UK_CRASH("Could not find proper size cells!\n");
+
+       /*
+        * QEMU will always provide us at least one bank of memory.
+        * unikraft will use the first bank for the time-being.
+        */
+       regs = fdt_getprop(_libkvmplat_dtb, fdt_mem, "reg", &prop_len);
+
+       /*
+        * The property must contain at least the start address
+        * and size, each of which is 8-bytes.
+        */
+       prop_min_len = (int)sizeof(fdt32_t) * (naddr + nsize);
+       if (regs == NULL || prop_len < prop_min_len)
+               UK_CRASH("Bad 'reg' property: %p %d\n", regs, prop_len);
+
+       /* If we have more than one memory bank, give a warning messasge */
+       if (prop_len > prop_min_len)
+               uk_printd(DLVL_WARN,
+                       "Currently, we support only one memory bank!\n");
+
+       mem_base = fdt64_to_cpu(regs[0]);
+       mem_size = fdt64_to_cpu(regs[1]);
+       if (mem_base > (uint64_t)&_text)
+               UK_CRASH("Fatal: Image outside of RAM\n");
+
+       max_addr = mem_base + mem_size;
+       _libkvmplat_pagetable =(void *) ALIGN_DOWN((size_t)&_end, __PAGE_SIZE);
+       _libkvmplat_heap_start = _libkvmplat_pagetable + PAGE_TABLE_SIZE;
+       _libkvmplat_mem_end = (void *) max_addr;
+
+       /* AArch64 require stack be 16-bytes alignment by default */
+       _libkvmplat_stack_top = (void *) ALIGN_UP(max_addr, __STACK_ALIGN_SIZE);
+}
+
 static void _dtb_get_cmdline(char *cmdline, size_t maxlen)
 {
        int fdtchosen, len;
@@ -72,5 +140,13 @@ void _libkvmplat_start(void *dtb_pointer)
        uk_printd(DLVL_INFO, "Entering from KVM (arm64)...\n");
 
        /* Get command line from DTB */
+
        _dtb_get_cmdline(cmdline, sizeof(cmdline));
+
+       /* Initialize memory from DTB */
+       _init_dtb_mem();
+
+       uk_printd(DLVL_INFO, "pagetable start: %p\n", _libkvmplat_pagetable);
+       uk_printd(DLVL_INFO, "     heap start: %p\n", _libkvmplat_heap_start);
+       uk_printd(DLVL_INFO, "      stack top: %p\n", _libkvmplat_stack_top);
 }
-- 
2.17.1


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.