[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 |