|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [PATCH 29/40] arm64: init the memory system before console/xenbus/gic
The mappings for console/xenbus/gic need several pages to setup
the page tables.
So we init the memory system before initiating the console/xenbus/gic,
and then we can allocate the pages which are needed by
the console/xenbus/gic mapping.
we use the 2M memory block for the memory.
Change-Id: I0d075478c107cf680d1a20989d57c0fcd727ab29
Jira: ENTOS-247
Signed-off-by: Huang Shijie <shijie.huang@xxxxxxx>
---
arch/arm/mm.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++
arch/arm/setup.c | 5 +++
include/arm/arch_mm.h | 1 +
mm.c | 5 ++-
4 files changed, 108 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mm.c b/arch/arm/mm.c
index edb734f..fb7886c 100644
--- a/arch/arm/mm.c
+++ b/arch/arm/mm.c
@@ -24,6 +24,102 @@ unsigned long allocate_ondemand(unsigned long n, unsigned
long alignment)
BUG();
}
+#if defined(__aarch64__)
+
+#include <arm64/pagetable.h>
+
+extern lpae_t boot_l1_pgtable[512];
+
+static inline void set_pgt_entry(lpae_t *ptr, lpae_t val)
+{
+ *ptr = val;
+ dsb(ishst);
+ isb();
+}
+
+static void build_pud(lpae_t *pgd, unsigned long vaddr, unsigned long vend,
+ paddr_t phys, long mem_type,
+ paddr_t (*new_page)(void), int level)
+{
+ lpae_t *pud;
+
+ pud = (lpae_t *)to_virt((*pgd) & ~ATTR_MASK_L) + l2_pgt_idx(vaddr);
+ do {
+ if (level == 2)
+ set_pgt_entry(pud, (phys & L2_MASK) | mem_type | L2_BLOCK);
+ vaddr += L2_SIZE;
+ phys += L2_SIZE;
+ pud++;
+ } while (vaddr < vend);
+}
+
+/* Setup the page table when the MMU is enabled */
+void build_pagetable(unsigned long vaddr, unsigned long start_pfn,
+ unsigned long max_pfn, long mem_type,
+ paddr_t (*new_page)(void), int level)
+{
+ paddr_t p_start;
+ unsigned long v_end, next;
+ lpae_t *pgd;
+
+ v_end = vaddr + max_pfn * PAGE_SIZE;
+ p_start = PFN_PHYS(start_pfn);
+
+ /* The boot_l1_pgtable can span 512G address space */
+ pgd = &boot_l1_pgtable[l1_pgt_idx(vaddr)];
+
+ do {
+ next = (vaddr + L1_SIZE);
+ if (next > v_end)
+ next = v_end;
+
+ if ((*pgd) == L1_INVAL) {
+ set_pgt_entry(pgd, (new_page()) | PT_PT);
+ }
+
+ build_pud(pgd, vaddr, next, p_start, mem_type, new_page, level);
+ p_start += next - vaddr;
+ vaddr = next;
+ pgd++;
+ } while (vaddr != v_end);
+}
+
+static unsigned long first_free_pfn;
+static paddr_t get_new_page(void)
+{
+ paddr_t new_page;
+
+ memset(pfn_to_virt(first_free_pfn), 0, PAGE_SIZE);
+ dsb(ishst);
+
+ new_page = PFN_PHYS(first_free_pfn);
+ first_free_pfn++;
+ return new_page;
+}
+
+/*
+ * This function will setup the page table for the memory system.
+ *
+ * Note: We get the page for page table from the first free PFN,
+ * the get_new_page() will increase the @first_free_pfn.
+ */
+void init_pagetable(unsigned long *start_pfn, unsigned long base_pfn,
+ unsigned long max_pfn)
+{
+ first_free_pfn = *start_pfn;
+
+ build_pagetable((unsigned long)pfn_to_virt(base_pfn), base_pfn,
+ max_pfn, BLOCK_DEF_ATTR, get_new_page, 2);
+ *start_pfn = first_free_pfn;
+}
+
+#else
+void init_pagetable(unsigned long *start_pfn, unsigned long base_pfn,
+ unsigned long max_pfn)
+{
+}
+#endif
+
void arch_init_mm(unsigned long *start_pfn_p, unsigned long *max_pfn_p)
{
int memory;
@@ -74,6 +170,8 @@ void arch_init_mm(unsigned long *start_pfn_p, unsigned long
*max_pfn_p)
heap_len = mem_size - (PFN_PHYS(*start_pfn_p) - mem_base);
*max_pfn_p = *start_pfn_p + PFN_DOWN(heap_len);
+ init_pagetable(start_pfn_p, PHYS_PFN(mem_base), PHYS_PFN(mem_size));
+
printk("Using pages %lu to %lu as free space for heap.\n", *start_pfn_p,
*max_pfn_p);
/* The device tree is probably in memory that we're about to hand over to
the page
diff --git a/arch/arm/setup.c b/arch/arm/setup.c
index bde30c6..61daca3 100644
--- a/arch/arm/setup.c
+++ b/arch/arm/setup.c
@@ -41,6 +41,11 @@ void arch_init(void *dtb_pointer, paddr_t physical_offset)
/* Map shared_info page */
HYPERVISOR_shared_info = map_shared_info(NULL);
+#if defined(__aarch64__)
+ /* We need to init the memory, and then init the console/xenbus/gic */
+ init_mm();
+#endif
+
get_console(NULL);
get_xenbus(NULL);
diff --git a/include/arm/arch_mm.h b/include/arm/arch_mm.h
index 6dfa61e..235e914 100644
--- a/include/arm/arch_mm.h
+++ b/include/arm/arch_mm.h
@@ -1,6 +1,7 @@
#ifndef _ARCH_MM_H_
#define _ARCH_MM_H_
+typedef uint64_t lpae_t;
typedef uint64_t paddr_t;
extern char _text, _etext, _erodata, _edata, _end, __bss_start;
diff --git a/mm.c b/mm.c
index 74565d1..b090a0a 100644
--- a/mm.c
+++ b/mm.c
@@ -384,12 +384,14 @@ void *sbrk(ptrdiff_t increment)
#endif
-
+static int mm_inited;
void init_mm(void)
{
unsigned long start_pfn, max_pfn;
+ if (mm_inited)
+ return;
printk("MM: Init\n");
get_max_pages();
@@ -407,6 +409,7 @@ void init_mm(void)
#ifdef CONFIG_BALLOON
nr_mem_pages = max_pfn;
#endif
+ mm_inited = 1;
}
void fini_mm(void)
--
2.7.4
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |