diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2014-03-21 21:04:40 +0400 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2014-04-02 01:35:54 +0400 |
commit | 06bd2824f7dcbfb8dcd13519239a53d13298d238 (patch) | |
tree | 249b0b2ae6c1b088c358b8b150dabe2b839c16db /arch/xtensa | |
parent | 6232791833785ae591b211609f6f7c4faa7c6e55 (diff) |
xtensa: handle memmap kernel option
This option is useful for reserving memory regions for secondary cores
in AMP configurations.
Implement the following memmap variants:
- memmap=nn[KMG]@ss[KMG]: force usage of a specific region of memory;
- memmap=nn[KMG]$ss[KMG]: mark specified memory as reserved;
- memmap=nn[KMG]: set end of memory.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'arch/xtensa')
-rw-r--r-- | arch/xtensa/kernel/setup.c | 1 | ||||
-rw-r--r-- | arch/xtensa/mm/init.c | 50 |
2 files changed, 51 insertions, 0 deletions
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 017c06aba9b..9757bb74e53 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -507,6 +507,7 @@ void __init setup_arch(char **cmdline_p) __pa(&_Level6InterruptVector_text_end), 0); #endif + parse_early_param(); bootmem_init(); unflatten_and_copy_device_tree(); diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 5d23697957b..d70ba9333f4 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -332,3 +332,53 @@ void free_initmem(void) { free_initmem_default(-1); } + +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); + add_sysmem_bank(start_at, start_at + mem_size); + break; + + case '$': + start_at = memparse(p + 1, &p); + mem_reserve(start_at, start_at + mem_size, 0); + break; + + case 0: + mem_reserve(mem_size, 0, 0); + break; + + default: + pr_warn("Unrecognized memmap syntax: %s\n", p); + break; + } +} + +static int __init parse_memmap_opt(char *str) +{ + while (str) { + char *k = strchr(str, ','); + + if (k) + *k++ = 0; + + parse_memmap_one(str); + str = k; + } + + return 0; +} +early_param("memmap", parse_memmap_opt); |