From: David Daney <david.daney@xxxxxxxxxx> Command line syntax is: mem=block:block_name1,block_name2,... A maximum of 4 blocks are currently supported Signed-off-by: David Daney <david.daney@xxxxxxxxxx> Signed-off-by: Carlos Munoz <carlos.munoz@xxxxxxxxxxxxxxxxxx> Signed-off-by: Corey Minyard <cminyard@xxxxxxxxxx> --- arch/mips/cavium-octeon/setup.c | 66 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 46e2bb0..2855d8d 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -198,6 +198,9 @@ static int octeon_uart; extern asmlinkage void handle_int(void); +/* Up to four blocks may be specified. */ +static char __initdata named_memory_blocks[4][CVMX_BOOTMEM_NAME_LEN]; + /** * Return non zero if we are currently running in the Octeon simulator * @@ -774,7 +777,26 @@ void __init prom_init(void) for (i = 0; i < argc; i++) { const char *arg = cvmx_phys_to_ptr(octeon_boot_desc_ptr->argv[i]); - if ((strncmp(arg, "MEM=", 4) == 0) || + if (strncmp(arg, "mem=block:", 10) == 0) { + const char *pos = arg + 10; + int j; + + for (j = 0; pos[0] && j < ARRAY_SIZE(named_memory_blocks); j++) { + int len; + char *comma = strchr(pos, ','); + if (comma) + len = comma - pos; + else + len = max(strlen(pos), ARRAY_SIZE(named_memory_blocks[0])); + strncpy(named_memory_blocks[j], pos, len); + if (comma) + pos = comma + 1; + else + break; + } + for (j = 0; j < ARRAY_SIZE(named_memory_blocks); j++) + pr_err("Named Block[%d] = \"%s\"\n", j, named_memory_blocks[j]); + } else if ((strncmp(arg, "MEM=", 4) == 0) || (strncmp(arg, "mem=", 4) == 0)) { max_memory = memparse(arg + 4, &p); if (max_memory == 0) @@ -875,10 +897,35 @@ void __init plat_mem_setup(void) uint64_t total; uint64_t crashk_end; int64_t memory; + const struct cvmx_bootmem_named_block_desc *named_block; total = 0; crashk_end = 0; + if (named_memory_blocks[0][0]) { + /* Memory from named blocks only */ + int i; + + for (i = 0; + named_memory_blocks[i][0] && i < ARRAY_SIZE(named_memory_blocks); + i++) { + named_block = cvmx_bootmem_find_named_block(named_memory_blocks[i]); + if (!named_block) { + pr_err("Error: Couldn't find cvmx_bootmem block \"%s\"", + named_memory_blocks[i]); + return; + } + pr_info("Adding memory from \"%s\": %016lx @ %016lx\n", + named_memory_blocks[i], + (unsigned long)named_block->size, + (unsigned long)named_block->base_addr); + add_memory_region(named_block->base_addr, named_block->size, + BOOT_MEM_RAM); + total += named_block->size; + } + goto mem_alloc_done; + } + /* * The Mips memory init uses the first memory location for * some memory vectors. When SPARSEMEM is in use, it doesn't @@ -901,18 +948,23 @@ void __init plat_mem_setup(void) crashk_end = crashk_base + crashk_size; } #endif - /* - * When allocating memory, we want incrementing addresses from - * bootmem_alloc so the code in add_memory_region can merge - * regions next to each other. - */ cvmx_bootmem_lock(); while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX) && (total < max_memory)) { +#if defined(CONFIG_64BIT) || defined(CONFIG_64BIT_PHYS_ADDR) memory = cvmx_bootmem_phy_alloc(mem_alloc_size, __pa_symbol(&_end), -1, 0x100000, CVMX_BOOTMEM_FLAG_NO_LOCKING); +#elif defined(CONFIG_HIGHMEM) + memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 1ull << 31, + 0x100000, + CVMX_BOOTMEM_FLAG_NO_LOCKING); +#else + memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 512 << 20, + 0x100000, + CVMX_BOOTMEM_FLAG_NO_LOCKING); +#endif if (memory >= 0) { u64 size = mem_alloc_size; @@ -942,7 +994,7 @@ void __init plat_mem_setup(void) } cvmx_bootmem_unlock(); #endif /* CONFIG_CRASH_DUMP */ - +mem_alloc_done: #ifdef CONFIG_CAVIUM_RESERVE32 /* * Now that we've allocated the kernel memory it is safe to -- 2.1.4