Exemplo n.º 1
0
static void __init mcf54xx_bootmem_alloc(void)
{
	unsigned long start_pfn;
	unsigned long memstart;

	/* _rambase and _ramend will be naturally page aligned */
	m68k_memory[0].addr = _rambase;
	m68k_memory[0].size = _ramend - _rambase;

	/* compute total pages in system */
	num_pages = (_ramend - _rambase) >> PAGE_SHIFT;

	/* page numbers */
	memstart = PAGE_ALIGN(_ramstart);
	min_low_pfn = _rambase >> PAGE_SHIFT;
	start_pfn = memstart >> PAGE_SHIFT;
	max_low_pfn = _ramend >> PAGE_SHIFT;
	high_memory = (void *)_ramend;

	m68k_virt_to_node_shift = fls(_ramend - _rambase - 1) - 6;
	module_fixup(NULL, __start_fixup, __stop_fixup);

	/* setup bootmem data */
	m68k_setup_node(0);
	memstart += init_bootmem_node(NODE_DATA(0), start_pfn,
		min_low_pfn, max_low_pfn);
	free_bootmem_node(NODE_DATA(0), memstart, _ramend - memstart);
}
Exemplo n.º 2
0
static u32 __init allocate_aperture(void) 
{
#ifdef CONFIG_DISCONTIGMEM
	pg_data_t *nd0 = NODE_DATA(0);
#else
	pg_data_t *nd0 = &contig_page_data;
#endif	
	u32 aper_size;
	void *p; 

	if (fallback_aper_order > 7) 
		fallback_aper_order = 7; 
	aper_size = (32 * 1024 * 1024) << fallback_aper_order; 

	/* 
	 * Aperture has to be naturally aligned. This means an 2GB aperture won't 
	 * have much chances to find a place in the lower 4GB of memory. 
	 * Unfortunately we cannot move it up because that would make the 
	 * IOMMU useless.
	 */
	p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 
	if (!p || __pa(p)+aper_size > 0xffffffff) {
		printk("Cannot allocate aperture memory hole (%p,%uK)\n",
		       p, aper_size>>10);
		if (p)
			free_bootmem_node(nd0, (unsigned long)p, aper_size); 
		return 0;
	}
Exemplo n.º 3
0
unsigned long __init setup_memory(void)
{
	unsigned long bootmap_size;
	unsigned long min_pfn;
	int nid;
	mem_prof_t *mp;

	max_low_pfn = 0;
	min_low_pfn = -1;

	mem_prof_init();

	for_each_online_node(nid) {
		mp = &mem_prof[nid];
		NODE_DATA(nid)=(pg_data_t *)&m32r_node_data[nid];
		NODE_DATA(nid)->bdata = &node_bdata[nid];
		min_pfn = mp->start_pfn;
		max_pfn = mp->start_pfn + mp->pages;
		bootmap_size = init_bootmem_node(NODE_DATA(nid), mp->free_pfn,
			mp->start_pfn, max_pfn);

		free_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn),
			PFN_PHYS(mp->pages));

		reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn),
			PFN_PHYS(mp->free_pfn - mp->start_pfn) + bootmap_size);

		if (max_low_pfn < max_pfn)
			max_low_pfn = max_pfn;

		if (min_low_pfn > min_pfn)
			min_low_pfn = min_pfn;
	}

#ifdef CONFIG_BLK_DEV_INITRD
	if (LOADER_TYPE && INITRD_START) {
		if (INITRD_START + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) {
			reserve_bootmem_node(NODE_DATA(0), INITRD_START,
				INITRD_SIZE);
			initrd_start = INITRD_START ?
				INITRD_START + PAGE_OFFSET : 0;

			initrd_end = initrd_start + INITRD_SIZE;
			printk("initrd:start[%08lx],size[%08lx]\n",
				initrd_start, INITRD_SIZE);
		} else {
			printk("initrd extends beyond end of memory "
				"(0x%08lx > 0x%08lx)\ndisabling initrd\n",
				INITRD_START + INITRD_SIZE,
				PFN_PHYS(max_low_pfn));

			initrd_start = 0;
		}
	}
#endif	/* CONFIG_BLK_DEV_INITRD */

	return max_low_pfn;
}
Exemplo n.º 4
0
static void __init dma32_free_bootmem(void)
{
    int node;

    if (end_pfn <= MAX_DMA32_PFN)
        return;

    if (!dma32_bootmem_ptr)
        return;

    for_each_online_node(node)
        free_bootmem_node(NODE_DATA(node), __pa(dma32_bootmem_ptr),
                  dma32_bootmem_size);

    dma32_bootmem_ptr = NULL;
    dma32_bootmem_size = 0;
}
Exemplo n.º 5
0
/* 
 * Free bootmem based on the e820 table for a node.
 */
void __init e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end)
{
	int i;
	for (i = 0; i < e820.nr_map; i++) {
		struct e820entry *ei = &e820.map[i]; 
		unsigned long last, addr;

		if (ei->type != E820_RAM || 
		    ei->addr+ei->size <= start || 
		    ei->addr >= end)
			continue;

		addr = round_up(ei->addr, PAGE_SIZE);
		if (addr < start) 
			addr = start;

		last = round_down(ei->addr + ei->size, PAGE_SIZE); 
		if (last >= end)
			last = end; 

		if (last > addr && last-addr >= PAGE_SIZE)
			free_bootmem_node(pgdat, addr, last-addr);
	}
}
Exemplo n.º 6
0
void __init setup_arch(char **cmdline_p)
{
#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_UNKNOWN)
	extern struct sh_machine_vector mv_unknown;
#endif
	struct sh_machine_vector *mv = NULL;
	char mv_name[MV_NAME_SIZE] = "";
	unsigned long mv_io_base = 0;
	int mv_mmio_enable = 0;
	unsigned long bootmap_size;
	unsigned long start_pfn, max_pfn, max_low_pfn;

#ifdef CONFIG_SH_EARLY_PRINTK
	sh_console_init();
#endif
	
	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);

#ifdef CONFIG_BLK_DEV_RAM
	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
#endif

	if (!MOUNT_ROOT_RDONLY)
		root_mountflags &= ~MS_RDONLY;
	init_mm.start_code = (unsigned long)&_text;
	init_mm.end_code = (unsigned long) &_etext;
	init_mm.end_data = (unsigned long) &_edata;
	init_mm.brk = (unsigned long) &_end;

	code_resource.start = virt_to_bus(&_text);
	code_resource.end = virt_to_bus(&_etext)-1;
	data_resource.start = virt_to_bus(&_etext);
	data_resource.end = virt_to_bus(&_edata)-1;

	parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable);

#ifdef CONFIG_CMDLINE_BOOL
	sprintf(*cmdline_p, CONFIG_CMDLINE);
#endif

#ifdef CONFIG_SH_GENERIC
	if (mv == NULL) {
		mv = &mv_unknown;
		if (*mv_name != '\0') {
			printk("Warning: Unsupported machine %s, using unknown\n",
			       mv_name);
		}
	}
	sh_mv = *mv;
#endif
#ifdef CONFIG_SH_UNKNOWN
	sh_mv = mv_unknown;
#endif

#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_UNKNOWN)
	if (mv_io_base != 0) {
		sh_mv.mv_inb = generic_inb;
		sh_mv.mv_inw = generic_inw;
		sh_mv.mv_inl = generic_inl;
		sh_mv.mv_outb = generic_outb;
		sh_mv.mv_outw = generic_outw;
		sh_mv.mv_outl = generic_outl;

		sh_mv.mv_inb_p = generic_inb_p;
		sh_mv.mv_inw_p = generic_inw_p;
		sh_mv.mv_inl_p = generic_inl_p;
		sh_mv.mv_outb_p = generic_outb_p;
		sh_mv.mv_outw_p = generic_outw_p;
		sh_mv.mv_outl_p = generic_outl_p;

		sh_mv.mv_insb = generic_insb;
		sh_mv.mv_insw = generic_insw;
		sh_mv.mv_insl = generic_insl;
		sh_mv.mv_outsb = generic_outsb;
		sh_mv.mv_outsw = generic_outsw;
		sh_mv.mv_outsl = generic_outsl;

		sh_mv.mv_isa_port2addr = generic_isa_port2addr;
		generic_io_base = mv_io_base;
	}
	if (mv_mmio_enable != 0) {
		sh_mv.mv_readb = generic_readb;
		sh_mv.mv_readw = generic_readw;
		sh_mv.mv_readl = generic_readl;
		sh_mv.mv_writeb = generic_writeb;
		sh_mv.mv_writew = generic_writew;
		sh_mv.mv_writel = generic_writel;
	}
#endif

#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
#define PFN_PHYS(x)	((x) << PAGE_SHIFT)

#ifdef CONFIG_DISCONTIGMEM
	NODE_DATA(0)->bdata = &discontig_node_bdata[0];
	NODE_DATA(1)->bdata = &discontig_node_bdata[1];

	bootmap_size = init_bootmem_node(NODE_DATA(1), 
					 PFN_UP(__MEMORY_START_2ND),
					 PFN_UP(__MEMORY_START_2ND),
					 PFN_DOWN(__MEMORY_START_2ND+__MEMORY_SIZE_2ND));
	free_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, __MEMORY_SIZE_2ND);
	reserve_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, bootmap_size);
#endif

	/*
	 * Find the highest page frame number we have available
	 */
	max_pfn = PFN_DOWN(__pa(memory_end));

	/*
	 * Determine low and high memory ranges:
	 */
	max_low_pfn = max_pfn;

 	/*
	 * Partially used pages are not usable - thus
	 * we are rounding upwards:
 	 */
	start_pfn = PFN_UP(__pa(&_end));
	/*
	 * Find a proper area for the bootmem bitmap. After this
	 * bootstrap step all allocations (until the page allocator
	 * is intact) must be done via bootmem_alloc().
	 */
	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
					 __MEMORY_START>>PAGE_SHIFT,
					 max_low_pfn);

	/*
	 * Register fully available low RAM pages with the bootmem allocator.
	 */
	{
		unsigned long curr_pfn, last_pfn, pages;

		/*
		 * We are rounding up the start address of usable memory:
		 */
		curr_pfn = PFN_UP(__MEMORY_START);
		/*
		 * ... and at the end of the usable range downwards:
		 */
		last_pfn = PFN_DOWN(__pa(memory_end));

		if (last_pfn > max_low_pfn)
			last_pfn = max_low_pfn;

		pages = last_pfn - curr_pfn;
		free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn),
				  PFN_PHYS(pages));
	}

	/*
	 * Reserve the kernel text and
	 * Reserve the bootmem bitmap. We do this in two steps (first step
	 * was init_bootmem()), because this catches the (definitely buggy)
	 * case of us accidentally initializing the bootmem allocator with
	 * an invalid RAM area.
	 */
	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE,
		(PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);

	/*
	 * reserve physical page 0 - it's a special BIOS page on many boxes,
	 * enabling clean reboots, SMP operation, laptop functions.
	 */
	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);

#ifdef CONFIG_BLK_DEV_INITRD
	if (LOADER_TYPE && INITRD_START) {
		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
			reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE);
			initrd_start =
				INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
			initrd_end = initrd_start + INITRD_SIZE;
		} else {
			printk("initrd extends beyond end of memory "
			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
				    INITRD_START + INITRD_SIZE,
				    max_low_pfn << PAGE_SHIFT);
			initrd_start = 0;
		}
	}
#endif

#if 0
	/*
	 * Request the standard RAM and ROM resources -
	 * they eat up PCI memory space
	 */
	request_resource(&iomem_resource, ram_resources+0);
	request_resource(&iomem_resource, ram_resources+1);
	request_resource(&iomem_resource, ram_resources+2);
	request_resource(ram_resources+1, &code_resource);
	request_resource(ram_resources+1, &data_resource);
	probe_roms();

	/* request I/O space for devices used on all i[345]86 PCs */
	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
		request_resource(&ioport_resource, standard_io_resources+i);
#endif

#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
	conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
	conswitchp = &dummy_con;
#endif
#endif

	/* Perform the machine specific initialisation */
	if (sh_mv.mv_init_arch != NULL) {
		sh_mv.mv_init_arch();
	}

#if defined(__SH4__)
	init_task.used_math = 0;
	init_task.flags &= ~PF_USEDFPU;
#endif

#ifdef CONFIG_UBC_WAKEUP
	/*
	 * Some brain-damaged loaders decided it would be a good idea to put
	 * the UBC to sleep. This causes some issues when it comes to things
	 * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB.  So ..
	 * we wake it up and hope that all is well.
	 */
	ubc_wakeup();
#endif

	paging_init();
}
Exemplo n.º 7
0
void __init setup_arch(char **cmdline_p)
{
	unsigned long bootmap_size;
	unsigned long start_pfn, max_pfn, max_low_pfn;

#ifdef CONFIG_EARLY_PRINTK
	extern void enable_early_printk(void);

	enable_early_printk();
#endif
#ifdef CONFIG_CMDLINE_BOOL
        strcpy(COMMAND_LINE, CONFIG_CMDLINE);
#endif

	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);

#ifdef CONFIG_BLK_DEV_RAM
	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
#endif

	if (!MOUNT_ROOT_RDONLY)
		root_mountflags &= ~MS_RDONLY;
	init_mm.start_code = (unsigned long) _text;
	init_mm.end_code = (unsigned long) _etext;
	init_mm.end_data = (unsigned long) _edata;
	init_mm.brk = (unsigned long) _end;

	code_resource.start = virt_to_bus(_text);
	code_resource.end = virt_to_bus(_etext)-1;
	data_resource.start = virt_to_bus(_etext);
	data_resource.end = virt_to_bus(_edata)-1;

	sh_mv_setup(cmdline_p);

#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
#define PFN_PHYS(x)	((x) << PAGE_SHIFT)

	/*
	 * Find the highest page frame number we have available
	 */
	max_pfn = PFN_DOWN(__pa(memory_end));

	/*
	 * Determine low and high memory ranges:
	 */
	max_low_pfn = max_pfn;

	/*
	 * Partially used pages are not usable - thus
	 * we are rounding upwards:
	 */
	start_pfn = PFN_UP(__pa(_end));

	/*
	 * Find a proper area for the bootmem bitmap. After this
	 * bootstrap step all allocations (until the page allocator
	 * is intact) must be done via bootmem_alloc().
	 */
	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
					 __MEMORY_START>>PAGE_SHIFT,
					 max_low_pfn);
	/*
	 * Register fully available low RAM pages with the bootmem allocator.
	 */
	{
		unsigned long curr_pfn, last_pfn, pages;

		/*
		 * We are rounding up the start address of usable memory:
		 */
		curr_pfn = PFN_UP(__MEMORY_START);
		/*
		 * ... and at the end of the usable range downwards:
		 */
		last_pfn = PFN_DOWN(__pa(memory_end));

		if (last_pfn > max_low_pfn)
			last_pfn = max_low_pfn;

		pages = last_pfn - curr_pfn;
		free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn),
				  PFN_PHYS(pages));
	}

	/*
	 * Reserve the kernel text and
	 * Reserve the bootmem bitmap. We do this in two steps (first step
	 * was init_bootmem()), because this catches the (definitely buggy)
	 * case of us accidentally initializing the bootmem allocator with
	 * an invalid RAM area.
	 */
	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE,
		(PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);

	/*
	 * reserve physical page 0 - it's a special BIOS page on many boxes,
	 * enabling clean reboots, SMP operation, laptop functions.
	 */
	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);

#ifdef CONFIG_BLK_DEV_INITRD
	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
	if (&__rd_start != &__rd_end) {
		LOADER_TYPE = 1;
		INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START;
		INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start;
	}

	if (LOADER_TYPE && INITRD_START) {
		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
			reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE);
			initrd_start =
				INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
			initrd_end = initrd_start + INITRD_SIZE;
		} else {
			printk("initrd extends beyond end of memory "
			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
				    INITRD_START + INITRD_SIZE,
				    max_low_pfn << PAGE_SHIFT);
			initrd_start = 0;
		}
	}
#endif

#ifdef CONFIG_DUMMY_CONSOLE
	conswitchp = &dummy_con;
#endif

	/* Perform the machine specific initialisation */
	platform_setup();

	paging_init();
}
Exemplo n.º 8
0
/*
 * paging_init() continues the virtual memory environment setup which
 * was begun by the code in arch/head.S.
 */
void __init paging_init(void)
{
	unsigned long zones_size[MAX_NR_ZONES] = { 0, };
	unsigned long min_addr, max_addr;
	unsigned long addr, size, end;
	int i;

#ifdef DEBUG
	{
		extern unsigned long availmem;
		printk ("start of paging_init (%p, %lx)\n",
			kernel_pg_dir, availmem);
	}
#endif

	/* Fix the cache mode in the page descriptors for the 680[46]0.  */
	if (CPU_IS_040_OR_060) {
		int i;
#ifndef mm_cachebits
		mm_cachebits = _PAGE_CACHE040;
#endif
		for (i = 0; i < 16; i++)
			pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
	}

	min_addr = m68k_memory[0].addr;
	max_addr = min_addr + m68k_memory[0].size;
	for (i = 1; i < m68k_num_memory;) {
		if (m68k_memory[i].addr < min_addr) {
			printk("Ignoring memory chunk at 0x%lx:0x%lx before the first chunk\n",
				m68k_memory[i].addr, m68k_memory[i].size);
			printk("Fix your bootloader or use a memfile to make use of this area!\n");
			m68k_num_memory--;
			memmove(m68k_memory + i, m68k_memory + i + 1,
				(m68k_num_memory - i) * sizeof(struct mem_info));
			continue;
		}
		addr = m68k_memory[i].addr + m68k_memory[i].size;
		if (addr > max_addr)
			max_addr = addr;
		i++;
	}
	m68k_memoffset = min_addr - PAGE_OFFSET;
	m68k_virt_to_node_shift = fls(max_addr - min_addr - 1) - 6;

	module_fixup(NULL, __start_fixup, __stop_fixup);
	flush_icache();

	high_memory = phys_to_virt(max_addr);

	min_low_pfn = availmem >> PAGE_SHIFT;
	max_low_pfn = max_addr >> PAGE_SHIFT;

	for (i = 0; i < m68k_num_memory; i++) {
		addr = m68k_memory[i].addr;
		end = addr + m68k_memory[i].size;
		m68k_setup_node(i);
		availmem = PAGE_ALIGN(availmem);
		availmem += init_bootmem_node(NODE_DATA(i),
					      availmem >> PAGE_SHIFT,
					      addr >> PAGE_SHIFT,
					      end >> PAGE_SHIFT);
	}

	/*
	 * Map the physical memory available into the kernel virtual
	 * address space. First initialize the bootmem allocator with
	 * the memory we already mapped, so map_node() has something
	 * to allocate.
	 */
	addr = m68k_memory[0].addr;
	size = m68k_memory[0].size;
	free_bootmem_node(NODE_DATA(0), availmem, min(INIT_MAPPED_SIZE, size) - (availmem - addr));
	map_node(0);
	if (size > INIT_MAPPED_SIZE)
		free_bootmem_node(NODE_DATA(0), addr + INIT_MAPPED_SIZE, size - INIT_MAPPED_SIZE);

	for (i = 1; i < m68k_num_memory; i++)
		map_node(i);

	flush_tlb_all();

	/*
	 * initialize the bad page table and bad page to point
	 * to a couple of allocated pages
	 */
	empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
	memset(empty_zero_page, 0, PAGE_SIZE);

	/*
	 * Set up SFC/DFC registers
	 */
	set_fs(KERNEL_DS);

#ifdef DEBUG
	printk ("before free_area_init\n");
#endif
	for (i = 0; i < m68k_num_memory; i++) {
		zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT;
		free_area_init_node(i, pg_data_map + i, zones_size,
				    m68k_memory[i].addr >> PAGE_SHIFT, NULL);
	}
}
Exemplo n.º 9
0
void __init do_init_bootmem(void)
{
	int nid;

	min_low_pfn = 0;
	max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;

	if (parse_numa_properties())
		setup_nonnuma();

	for (nid = 0; nid < numnodes; nid++) {
		unsigned long start_paddr, end_paddr;
		int i;
		unsigned long bootmem_paddr;
		unsigned long bootmap_pages;

		if (node_data[nid].node_spanned_pages == 0)
			continue;

		start_paddr = node_data[nid].node_start_pfn * PAGE_SIZE;
		end_paddr = start_paddr + 
				(node_data[nid].node_spanned_pages * PAGE_SIZE);

		dbg("node %d\n", nid);
		dbg("start_paddr = %lx\n", start_paddr);
		dbg("end_paddr = %lx\n", end_paddr);

		NODE_DATA(nid)->bdata = &plat_node_bdata[nid];

		bootmap_pages = bootmem_bootmap_pages((end_paddr - start_paddr) >> PAGE_SHIFT);
		dbg("bootmap_pages = %lx\n", bootmap_pages);

		bootmem_paddr = lmb_alloc_base(bootmap_pages << PAGE_SHIFT,
				PAGE_SIZE, end_paddr);
		dbg("bootmap_paddr = %lx\n", bootmem_paddr);

		init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
				  start_paddr >> PAGE_SHIFT,
				  end_paddr >> PAGE_SHIFT);

		for (i = 0; i < lmb.memory.cnt; i++) {
			unsigned long physbase, size;
			unsigned long type = lmb.memory.region[i].type;

			if (type != LMB_MEMORY_AREA)
				continue;

			physbase = lmb.memory.region[i].physbase;
			size = lmb.memory.region[i].size;

			if (physbase < end_paddr &&
			    (physbase+size) > start_paddr) {
				/* overlaps */
				if (physbase < start_paddr) {
					size -= start_paddr - physbase;
					physbase = start_paddr;
				}

				if (size > end_paddr - start_paddr)
					size = end_paddr - start_paddr;

				dbg("free_bootmem %lx %lx\n", physbase, size);
				free_bootmem_node(NODE_DATA(nid), physbase,
						  size);
			}
		}

		for (i = 0; i < lmb.reserved.cnt; i++) {
			unsigned long physbase = lmb.reserved.region[i].physbase;
			unsigned long size = lmb.reserved.region[i].size;

			if (physbase < end_paddr &&
			    (physbase+size) > start_paddr) {
				/* overlaps */
				if (physbase < start_paddr) {
					size -= start_paddr - physbase;
					physbase = start_paddr;
				}

				if (size > end_paddr - start_paddr)
					size = end_paddr - start_paddr;

				dbg("reserve_bootmem %lx %lx\n", physbase,
				    size);
				reserve_bootmem_node(NODE_DATA(nid), physbase,
						     size);
			}
		}
	}
}