/* Add xenheap memory that was not already added to the boot allocator. */ init_xenheap_pages(pfn_to_paddr(xenheap_mfn_start), pfn_to_paddr(boot_mfn_start)); end_boot_allocator(); } #else /* CONFIG_ARM_64 */ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size) { paddr_t ram_start = ~0; paddr_t ram_end = 0; paddr_t ram_size = 0; int bank; unsigned long dtb_pages; void *fdt; total_pages = 0; for ( bank = 0 ; bank < early_info.mem.nr_banks; bank++ ) { paddr_t bank_start = early_info.mem.bank[bank].start; paddr_t bank_size = early_info.mem.bank[bank].size; paddr_t bank_end = bank_start + bank_size; paddr_t s, e; paddr_t new_ram_size = ram_size + bank_size; paddr_t new_ram_start = min(ram_start,bank_start); paddr_t new_ram_end = max(ram_end,bank_end); /* * We allow non-contigious regions so long as at least half of * the total RAM region actually contains RAM. We actually * fudge this slightly and require that adding the current * bank does not cause us to violate this restriction. * * This restriction ensures that the frametable (which is not * currently sparse) does not consume all available RAM. */ if ( bank > 0 && 2 * new_ram_size < new_ram_end - new_ram_start ) /* Would create memory map which is too sparse, so stop here. */ break; ram_start = new_ram_start; ram_end = new_ram_end; ram_size = new_ram_size; setup_xenheap_mappings(bank_start>>PAGE_SHIFT, bank_size>>PAGE_SHIFT); s = bank_start; while ( s < bank_end ) { paddr_t n = bank_end; e = next_module(s, &n); if ( e == ~(paddr_t)0 ) { e = n = bank_end; } if ( e > bank_end ) e = bank_end; xenheap_mfn_end = e; dt_unreserved_regions(s, e, init_boot_pages, 0); s = n; } } if ( bank != early_info.mem.nr_banks ) { early_printk("WARNING: only using %d out of %d memory banks\n", bank, early_info.mem.nr_banks); early_info.mem.nr_banks = bank; } total_pages += ram_size >> PAGE_SHIFT; xenheap_virt_end = XENHEAP_VIRT_START + ram_end - ram_start; xenheap_mfn_start = ram_start >> PAGE_SHIFT; xenheap_mfn_end = ram_end >> PAGE_SHIFT; xenheap_max_mfn(xenheap_mfn_end); /* * Need enough mapped pages for copying the DTB. */ dtb_pages = (dtb_size + PAGE_SIZE-1) >> PAGE_SHIFT; /* Copy the DTB. */ fdt = mfn_to_virt(alloc_boot_pages(dtb_pages, 1)); copy_from_paddr(fdt, dtb_paddr, dtb_size, BUFFERABLE); device_tree_flattened = fdt; setup_frametable_mappings(ram_start, ram_end); max_page = PFN_DOWN(ram_end); end_boot_allocator(); }
/* Add xenheap memory that was not already added to the boot allocator. */ init_xenheap_pages(pfn_to_paddr(xenheap_mfn_start), pfn_to_paddr(boot_mfn_start)); end_boot_allocator(); } #else /* CONFIG_ARM_64 */ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size) { paddr_t ram_start = ~0; paddr_t ram_end = 0; paddr_t ram_size = 0; int bank; unsigned long dtb_pages; void *fdt; init_pdx(); total_pages = 0; for ( bank = 0 ; bank < bootinfo.mem.nr_banks; bank++ ) { paddr_t bank_start = bootinfo.mem.bank[bank].start; paddr_t bank_size = bootinfo.mem.bank[bank].size; paddr_t bank_end = bank_start + bank_size; paddr_t s, e; ram_size = ram_size + bank_size; ram_start = min(ram_start,bank_start); ram_end = max(ram_end,bank_end); setup_xenheap_mappings(bank_start>>PAGE_SHIFT, bank_size>>PAGE_SHIFT); s = bank_start; while ( s < bank_end ) { paddr_t n = bank_end; e = next_module(s, &n); if ( e == ~(paddr_t)0 ) { e = n = bank_end; } if ( e > bank_end ) e = bank_end; xenheap_mfn_end = e; dt_unreserved_regions(s, e, init_boot_pages, 0); s = n; } } total_pages += ram_size >> PAGE_SHIFT; xenheap_virt_end = XENHEAP_VIRT_START + ram_end - ram_start; xenheap_mfn_start = ram_start >> PAGE_SHIFT; xenheap_mfn_end = ram_end >> PAGE_SHIFT; xenheap_max_mfn(xenheap_mfn_end); /* * Need enough mapped pages for copying the DTB. */ dtb_pages = (dtb_size + PAGE_SIZE-1) >> PAGE_SHIFT; /* Copy the DTB. */ fdt = mfn_to_virt(alloc_boot_pages(dtb_pages, 1)); copy_from_paddr(fdt, dtb_paddr, dtb_size); device_tree_flattened = fdt; setup_frametable_mappings(ram_start, ram_end); max_page = PFN_DOWN(ram_end); end_boot_allocator(); }