Hi Barry, On Wed, Nov 18, 2020 at 07:33:14PM +1300, Barry Song wrote: > memmap should be an useful kernel parameter which has been supported by > x86, mips and xtensa.
Why is this parameter should be useful for ARM64? My understanding is that it is required only to work around really broken bootloaders, isn't it? > This patch adds support for ARM64. At this stage, > the below two modes are supported only: > memmap=nn[KMG]@ss[KMG] > Force usage of a specific region of memory > > memmap=nn[KMG]$ss[KMG] > Region of memory to be reserved is from ss to ss+nn > > If users set memmap=exactmap before memmap=nn[KMG]@ss[KMG], they will > get the exact memory specified by memmap=nn[KMG]@ss[KMG]. For example, > on one machine with 4GB memory, "memmap=exactmap memmap=1G@1G" will > make kernel use the memory from 1GB to 2GB only. > > Signed-off-by: Barry Song <song.bao....@hisilicon.com> > --- > arch/arm64/mm/init.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 59 insertions(+) > > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c > index 095540667f0f..f1c6bfdbc953 100644 > --- a/arch/arm64/mm/init.c > +++ b/arch/arm64/mm/init.c > @@ -235,6 +235,65 @@ static int __init early_mem(char *p) > } > early_param("mem", early_mem); > > +static int need_remove_real_memblock __initdata; > + > +static void __init parse_memmap_one(char *p) > +{ > + char *oldp; > + unsigned long start_at, mem_size; > + > + if (!p) > + return; > + > + if (!strncmp(p, "exactmap", 8)) { > + need_remove_real_memblock = 1; > + return; > + } > + > + oldp = p; > + mem_size = memparse(p, &p); > + if (p == oldp) > + return; > + > + switch (*p) { > + case '@': > + start_at = memparse(p + 1, &p); > + /* > + * use the exactmap defined by nn[KMG]@ss[KMG], remove > + * memblock populated by DT etc. > + */ > + if (need_remove_real_memblock) { > + need_remove_real_memblock = 0; > + memblock_remove(0, ULLONG_MAX); > + } > + memblock_add(start_at, mem_size); > + break; > + case '$': > + start_at = memparse(p + 1, &p); > + memblock_reserve(start_at, mem_size); > + 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); > + > static int __init early_init_dt_scan_usablemem(unsigned long node, > const char *uname, int depth, void *data) > { > -- > 2.25.1 > -- Sincerely yours, Mike.