/* Only e800 has 128MB RAM */ void __init eseries_fixup(struct tag *tags, char **cmdline) { if (machine_is_e800()) memblock_add(0xa0000000, SZ_128M); else memblock_add(0xa0000000, SZ_64M); }
static void __init fixup_corgi(struct tag *tags, char **cmdline) { sharpsl_save_param(); if (machine_is_corgi()) memblock_add(0xa0000000, SZ_32M); else memblock_add(0xa0000000, SZ_64M); }
/* * Setup the memory banks. */ void realview_fixup(struct tag *tags, char **from) { /* * Most RealView platforms have 512MB contiguous RAM at 0x70000000. * Half of this is mirrored at 0. */ #ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET memblock_add(0x70000000, SZ_512M); #else memblock_add(0, SZ_256M); #endif }
static void __init fixup_edb7211(struct tag *tags, char **cmdline) { /* * Bank start addresses are not present in the information * passed in from the boot loader. We could potentially * detect them, but instead we hard-code them. * * Banks sizes _are_ present in the param block, but we're * not using that information yet. */ memblock_add(0xc0000000, SZ_8M); memblock_add(0xc1000000, SZ_8M); }
static void realview_pbx_fixup(struct tag *tags, char **from) { #ifdef CONFIG_SPARSEMEM /* * Memory configuration with SPARSEMEM enabled on RealView PBX (see * asm/mach/memory.h for more information). */ memblock_add(0, SZ_256M); memblock_add(0x20000000, SZ_512M); memblock_add(0x80000000, SZ_256M); #else realview_fixup(tags, from); #endif }
void __init wii_memory_fixups(void) { struct memblock_region *p = memblock.memory.regions; /* * This is part of a workaround to allow the use of two * discontinuous RAM ranges on the Wii, even if this is * currently unsupported on 32-bit PowerPC Linux. * * We coalesce the two memory ranges of the Wii into a * single range, then create a reservation for the "hole" * between both ranges. */ BUG_ON(memblock.memory.cnt != 2); BUG_ON(!page_aligned(p[0].base) || !page_aligned(p[1].base)); /* trim unaligned tail */ memblock_remove(ALIGN(p[1].base + p[1].size, PAGE_SIZE), (phys_addr_t)ULLONG_MAX); /* determine hole, add & reserve them */ wii_hole_start = ALIGN(p[0].base + p[0].size, PAGE_SIZE); wii_hole_size = p[1].base - wii_hole_start; memblock_add(wii_hole_start, wii_hole_size); memblock_reserve(wii_hole_start, wii_hole_size); BUG_ON(memblock.memory.cnt != 1); __memblock_dump_all(); /* allow ioremapping the address space in the hole */ __allow_ioremap_reserved = 1; }
static int pseries_add_memory(struct device_node *np) { const char *type; const unsigned int *regs; unsigned long base; unsigned int lmb_size; int ret = -EINVAL; /* * Check to see if we are actually adding memory */ type = of_get_property(np, "device_type", NULL); if (type == NULL || strcmp(type, "memory") != 0) return 0; /* * Find the base and size of the memblock */ regs = of_get_property(np, "reg", NULL); if (!regs) return ret; base = *(unsigned long *)regs; lmb_size = regs[3]; /* * Update memory region to represent the memory add */ ret = memblock_add(base, lmb_size); return (ret < 0) ? -EINVAL : 0; }
static int pseries_drconf_memory(unsigned long *base, unsigned int action) { struct device_node *np; const unsigned long *lmb_size; int rc; np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); if (!np) return -EINVAL; lmb_size = of_get_property(np, "ibm,lmb-size", NULL); if (!lmb_size) { of_node_put(np); return -EINVAL; } if (action == PSERIES_DRCONF_MEM_ADD) { rc = memblock_add(*base, *lmb_size); rc = (rc < 0) ? -EINVAL : 0; } else if (action == PSERIES_DRCONF_MEM_REMOVE) { rc = pseries_remove_memblock(*base, *lmb_size); } else { rc = -EINVAL; } of_node_put(np); return rc; }
static void __init parse_memmap_one(char *p) { char *oldp; unsigned long start_at, mem_size; if (!p) return; oldp = p; mem_size = memparse(p, &p); if (p == oldp) return; switch (*p) { case '@': start_at = memparse(p + 1, &p); memblock_add(start_at, mem_size); break; case '$': start_at = memparse(p + 1, &p); memblock_reserve(start_at, mem_size); break; case 0: memblock_reserve(mem_size, -mem_size); break; default: pr_warn("Unrecognized memmap syntax: %s\n", p); break; } }
static void realview_pb1176_fixup(struct tag *tags, char **from) { /* * RealView PB1176 only has 128MB of RAM mapped at 0. */ memblock_add(0, SZ_128M); }
void __init cf_bootmem_alloc(void) { unsigned long memstart; /* _rambase and _ramend will be naturally page aligned */ m68k_memory[0].addr = _rambase; m68k_memory[0].size = _ramend - _rambase; memblock_add(m68k_memory[0].addr, m68k_memory[0].size); /* compute total pages in system */ num_pages = PFN_DOWN(_ramend - _rambase); /* page numbers */ memstart = PAGE_ALIGN(_ramstart); min_low_pfn = PFN_DOWN(_rambase); max_pfn = max_low_pfn = PFN_DOWN(_ramend); high_memory = (void *)_ramend; /* Reserve kernel text/data/bss */ memblock_reserve(memstart, memstart - _rambase); m68k_virt_to_node_shift = fls(_ramend - 1) - 6; module_fixup(NULL, __start_fixup, __stop_fixup); /* setup node data */ m68k_setup_node(0); }
/* * First memory setup routine called from setup_arch() * 1. setup swapper's mm @init_mm * 2. Count the pages we have and setup bootmem allocator * 3. zone setup */ void __init setup_arch_memory(void) { unsigned long zones_size[MAX_NR_ZONES]; unsigned long end_mem = CONFIG_LINUX_LINK_BASE + arc_mem_sz; 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; /* * We do it here, so that memory is correctly instantiated * even if "mem=xxx" cmline over-ride is given and/or * DT has memory node. Each causes an update to @arc_mem_sz * and we finally add memory one here */ memblock_add(CONFIG_LINUX_LINK_BASE, arc_mem_sz); /*------------- externs in mm need setting up ---------------*/ /* first page of system - kernel .vector starts here */ min_low_pfn = ARCH_PFN_OFFSET; /* Last usable page of low mem (no HIGHMEM yet for ARC port) */ max_low_pfn = max_pfn = PFN_DOWN(end_mem); max_mapnr = max_low_pfn - min_low_pfn; /*------------- reserve kernel image -----------------------*/ memblock_reserve(CONFIG_LINUX_LINK_BASE, __pa(_end) - CONFIG_LINUX_LINK_BASE); #ifdef CONFIG_BLK_DEV_INITRD /*------------- reserve initrd image -----------------------*/ if (initrd_start) memblock_reserve(__pa(initrd_start), initrd_end - initrd_start); #endif memblock_dump_all(); /*-------------- node setup --------------------------------*/ memset(zones_size, 0, sizeof(zones_size)); zones_size[ZONE_NORMAL] = max_mapnr; /* * We can't use the helper free_area_init(zones[]) because it uses * PAGE_OFFSET to compute the @min_low_pfn which would be wrong * when our kernel doesn't start at PAGE_OFFSET, i.e. * PAGE_OFFSET != CONFIG_LINUX_LINK_BASE */ free_area_init_node(0, /* node-id */ zones_size, /* num pages per zone */ min_low_pfn, /* first pfn of node */ NULL); /* NO holes */ high_memory = (void *)end_mem; }
static int __init parse_tag_mem(const bp_tag_t *tag) { struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data); if (mi->type != MEMORY_TYPE_CONVENTIONAL) return -1; return memblock_add(mi->start, mi->end - mi->start); }
static int pseries_update_drconf_memory(struct of_reconfig_data *pr) { struct of_drconf_cell *new_drmem, *old_drmem; unsigned long memblock_size; u32 entries; __be32 *p; int i, rc = -EINVAL; if (rtas_hp_event) return 0; memblock_size = pseries_memory_block_size(); if (!memblock_size) return -EINVAL; p = (__be32 *) pr->old_prop->value; if (!p) return -EINVAL; /* The first int of the property is the number of lmb's described * by the property. This is followed by an array of of_drconf_cell * entries. Get the number of entries and skip to the array of * of_drconf_cell's. */ entries = be32_to_cpu(*p++); old_drmem = (struct of_drconf_cell *)p; p = (__be32 *)pr->prop->value; p++; new_drmem = (struct of_drconf_cell *)p; for (i = 0; i < entries; i++) { if ((be32_to_cpu(old_drmem[i].flags) & DRCONF_MEM_ASSIGNED) && (!(be32_to_cpu(new_drmem[i].flags) & DRCONF_MEM_ASSIGNED))) { rc = pseries_remove_memblock( be64_to_cpu(old_drmem[i].base_addr), memblock_size); break; } else if ((!(be32_to_cpu(old_drmem[i].flags) & DRCONF_MEM_ASSIGNED)) && (be32_to_cpu(new_drmem[i].flags) & DRCONF_MEM_ASSIGNED)) { rc = memblock_add(be64_to_cpu(old_drmem[i].base_addr), memblock_size); rc = (rc < 0) ? -EINVAL : 0; break; } } return rc; }
/* * On SH machines the conventional approach is to stash system RAM * in node 0, and other memory blocks in to node 1 and up, ordered by * latency. Each node's pgdat is node-local at the beginning of the node, * immediately followed by the node mem map. */ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) { unsigned long bootmap_pages; unsigned long start_pfn, end_pfn; unsigned long bootmem_paddr; /* Don't allow bogus node assignment */ BUG_ON(nid > MAX_NUMNODES || nid <= 0); start_pfn = start >> PAGE_SHIFT; end_pfn = end >> PAGE_SHIFT; pmb_bolt_mapping((unsigned long)__va(start), start, end - start, PAGE_KERNEL); memblock_add(start, end - start); __add_active_range(nid, start_pfn, end_pfn); /* Node-local pgdat */ NODE_DATA(nid) = __va(memblock_alloc_base(sizeof(struct pglist_data), SMP_CACHE_BYTES, end)); memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; NODE_DATA(nid)->node_start_pfn = start_pfn; NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; /* Node-local bootmap */ bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); bootmem_paddr = memblock_alloc_base(bootmap_pages << PAGE_SHIFT, PAGE_SIZE, end); init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, start_pfn, end_pfn); free_bootmem_with_active_regions(nid, end_pfn); /* Reserve the pgdat and bootmap space with the bootmem allocator */ reserve_bootmem_node(NODE_DATA(nid), start_pfn << PAGE_SHIFT, sizeof(struct pglist_data), BOOTMEM_DEFAULT); reserve_bootmem_node(NODE_DATA(nid), bootmem_paddr, bootmap_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); /* It's up */ node_set_online(nid); /* Kick sparsemem */ sparse_memory_present_with_active_regions(nid); }
void __init early_init_dt_add_memory_arch(u64 base, u64 size) { base &= PAGE_MASK; size &= PAGE_MASK; if (base + size < PHYS_OFFSET) { pr_warning("Ignoring memory block 0x%llx - 0x%llx\n", base, base + size); return; } if (base < PHYS_OFFSET) { pr_warning("Ignoring memory range 0x%llx - 0x%llx\n", base, PHYS_OFFSET); size -= PHYS_OFFSET - base; base = PHYS_OFFSET; } memblock_add(base, size); }
static int pseries_update_drconf_memory(struct of_prop_reconfig *pr) { struct of_drconf_cell *new_drmem, *old_drmem; unsigned long memblock_size; u32 entries; u32 *p; int i, rc = -EINVAL; memblock_size = get_memblock_size(); if (!memblock_size) return -EINVAL; p = (u32 *)of_get_property(pr->dn, "ibm,dynamic-memory", NULL); if (!p) return -EINVAL; /* The first int of the property is the number of lmb's described * by the property. This is followed by an array of of_drconf_cell * entries. Get the niumber of entries and skip to the array of * of_drconf_cell's. */ entries = *p++; old_drmem = (struct of_drconf_cell *)p; p = (u32 *)pr->prop->value; p++; new_drmem = (struct of_drconf_cell *)p; for (i = 0; i < entries; i++) { if ((old_drmem[i].flags & DRCONF_MEM_ASSIGNED) && (!(new_drmem[i].flags & DRCONF_MEM_ASSIGNED))) { rc = pseries_remove_memblock(old_drmem[i].base_addr, memblock_size); break; } else if ((!(old_drmem[i].flags & DRCONF_MEM_ASSIGNED)) && (new_drmem[i].flags & DRCONF_MEM_ASSIGNED)) { rc = memblock_add(old_drmem[i].base_addr, memblock_size); rc = (rc < 0) ? -EINVAL : 0; break; } } return rc; }
void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size) { const u64 phys_offset = __pa(PAGE_OFFSET); base &= PAGE_MASK; size &= PAGE_MASK; if (base + size < phys_offset) { pr_warning("Ignoring memory block 0x%llx - 0x%llx\n", base, base + size); return; } if (base < phys_offset) { pr_warning("Ignoring memory range 0x%llx - 0x%llx\n", base, phys_offset); size -= phys_offset - base; base = phys_offset; } memblock_add(base, size); }
void __init bootmem_init(void) { struct memblock_region *reg; unsigned long bootmap_size; unsigned long free_pfn, end_pfn, start_pfn; init_mm.start_code = (unsigned long)_stext; init_mm.end_code = (unsigned long)_etext; init_mm.end_data = (unsigned long)_edata; init_mm.brk = (unsigned long)_end; memblock_init(); memblock_add(memory_start, memory_end); if(((unsigned long)__pa(_end) < memory_start) || ((unsigned long)__pa(_end) > memory_end)) printk("BUG: your kernel is not located in the ddr sdram"); start_pfn = PFN_UP(memory_start); free_pfn = PFN_UP(__pa((unsigned long)_end)); end_pfn = PFN_DOWN(memory_end); //memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(free_pfn - start_pfn)); memblock_reserve(__pa(_stext), _end - _stext); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && initrd_end && initrd_start < initrd_end) { memblock_reserve(initrd_start, initrd_end - initrd_start); } #endif bootmap_size = init_bootmem(free_pfn, end_pfn); memblock_reserve(PFN_PHYS(free_pfn), bootmap_size); free_bootmem(PFN_PHYS(free_pfn), PFN_PHYS(end_pfn - free_pfn)); for_each_memblock(reserved, reg) reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); memory_start += PAGE_OFFSET; memory_end += PAGE_OFFSET; memblock_analyze(); memblock_dump_all(); }
/** * omap_ram_console_register() - device_initcall to register ramconsole device */ static int __init omap_ram_console_register(void) { int ret; if (!omap_ramconsole_inited) return -ENODEV; ret = platform_device_register(&ram_console_device); if (ret) { pr_err("%s: unable to register ram console device:" "start=0x%08x, end=0x%08x, ret=%d\n", __func__, (u32)ram_console_resources[0].start, (u32)ram_console_resources[0].end, ret); memblock_add(ram_console_resources[0].start, (ram_console_resources[0].end - ram_console_resources[0].start + 1)); } return ret; }
static int pseries_drconf_memory(unsigned long *base, unsigned int action) { unsigned long memblock_size; int rc; memblock_size = get_memblock_size(); if (!memblock_size) return -EINVAL; if (action == PSERIES_DRCONF_MEM_ADD) { rc = memblock_add(*base, memblock_size); rc = (rc < 0) ? -EINVAL : 0; } else if (action == PSERIES_DRCONF_MEM_REMOVE) { rc = pseries_remove_memblock(*base, memblock_size); } else { rc = -EINVAL; } return rc; }
void __init memblock_x86_fill(void) { int i; unsigned long long end; for (i = 0; i < e820.nr_entries; i++) { struct e820entry *ei = &e820.map[i]; end = ei->addr + ei->size; /* this will filter > 4GB DRAM in 32-bit NONPAE kernel */ if (end != (resource_size_t)end) continue; if (ei->type != E820_RAM) continue; memblock_add(ei->addr, ei->size); } /* throw away partial pages */ memblock_trim_memory(PAGE_SIZE); }
static int pseries_add_memory(struct device_node *np) { const char *type; const unsigned int *regs; unsigned long base; unsigned int lmb_size; int ret = -EINVAL; type = of_get_property(np, "device_type", NULL); if (type == NULL || strcmp(type, "memory") != 0) return 0; regs = of_get_property(np, "reg", NULL); if (!regs) return ret; base = *(unsigned long *)regs; lmb_size = regs[3]; ret = memblock_add(base, lmb_size); return (ret < 0) ? -EINVAL : 0; }
static int dlpar_add_lmb_memory(struct of_drconf_cell *lmb) { struct memory_block *mem_block; unsigned long block_sz; int nid, rc; block_sz = memory_block_size_bytes(); /* Find the node id for this address */ nid = memory_add_physaddr_to_nid(lmb->base_addr); /* Add the memory */ rc = add_memory(nid, lmb->base_addr, block_sz); if (rc) return rc; /* Register this block of memory */ rc = memblock_add(lmb->base_addr, block_sz); if (rc) { remove_memory(nid, lmb->base_addr, block_sz); return rc; } mem_block = lmb_to_memblock(lmb); if (!mem_block) { remove_memory(nid, lmb->base_addr, block_sz); return -EINVAL; } rc = device_online(&mem_block->dev); put_device(&mem_block->dev); if (rc) { remove_memory(nid, lmb->base_addr, block_sz); return rc; } lmb->flags |= DRCONF_MEM_ASSIGNED; return 0; }
void __init generic_mem_init(void) { memblock_add(__MEMORY_START, __MEMORY_SIZE); }
void __init early_init_dt_add_memory_arch(u64 base, u64 size) { memblock_add(base, size); }
void __init early_init_dt_add_memory_arch(u64 base, u64 size) { size &= PAGE_MASK; memblock_add(base, size); }
static void __init fixup_poodle(struct tag *tags, char **cmdline) { sharpsl_save_param(); memblock_add(0xa0000000, SZ_32M); }
/* * First memory setup routine called from setup_arch() * 1. setup swapper's mm @init_mm * 2. Count the pages we have and setup bootmem allocator * 3. zone setup */ void __init setup_arch_memory(void) { unsigned long zones_size[MAX_NR_ZONES]; unsigned long zones_holes[MAX_NR_ZONES]; 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; /* first page of system - kernel .vector starts here */ min_low_pfn = ARCH_PFN_OFFSET; /* Last usable page of low mem */ max_low_pfn = max_pfn = PFN_DOWN(low_mem_start + low_mem_sz); #ifdef CONFIG_HIGHMEM min_high_pfn = PFN_DOWN(high_mem_start); max_pfn = PFN_DOWN(high_mem_start + high_mem_sz); #endif max_mapnr = max_pfn - min_low_pfn; /*------------- bootmem allocator setup -----------------------*/ /* * seed the bootmem allocator after any DT memory node parsing or * "mem=xxx" cmdline overrides have potentially updated @arc_mem_sz * * Only low mem is added, otherwise we have crashes when allocating * mem_map[] itself. NO_BOOTMEM allocates mem_map[] at the end of * avail memory, ending in highmem with a > 32-bit address. However * it then tries to memset it with a truncaed 32-bit handle, causing * the crash */ memblock_add(low_mem_start, low_mem_sz); memblock_reserve(low_mem_start, __pa(_end) - low_mem_start); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) memblock_reserve(__pa(initrd_start), initrd_end - initrd_start); #endif memblock_dump_all(); /*----------------- node/zones setup --------------------------*/ memset(zones_size, 0, sizeof(zones_size)); memset(zones_holes, 0, sizeof(zones_holes)); zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn; zones_holes[ZONE_NORMAL] = 0; #ifdef CONFIG_HIGHMEM zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn; /* This handles the peripheral address space hole */ zones_holes[ZONE_HIGHMEM] = min_high_pfn - max_low_pfn; #endif /* * We can't use the helper free_area_init(zones[]) because it uses * PAGE_OFFSET to compute the @min_low_pfn which would be wrong * when our kernel doesn't start at PAGE_OFFSET, i.e. * PAGE_OFFSET != CONFIG_LINUX_LINK_BASE */ free_area_init_node(0, /* node-id */ zones_size, /* num pages per zone */ min_low_pfn, /* first pfn of node */ zones_holes); /* holes */ #ifdef CONFIG_HIGHMEM high_memory = (void *)(min_high_pfn << PAGE_SHIFT); kmap_init(); #endif }
static void __init spitz_fixup(struct tag *tags, char **cmdline) { sharpsl_save_param(); memblock_add(0xa0000000, SZ_64M); }